• HNOI2012永无乡


    fhq treap+启发式合并,将小的合并到大的上面,复杂度NlogN。

    最好的一点是通过dfs将一个子树内的元素转到另一个元素上。

    By:大奕哥

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=100005;
     4 int n,m,f[N],a[N],ma[N];
     5 struct node
     6 {
     7     int l,r,s,rnd,v;
     8 }t[N];
     9 int get(int x){return f[x]==x?x:f[x]=get(f[x]);}
    10 void update(int x){t[x].s=t[t[x].l].s+t[t[x].r].s+1;}
    11 void split(int now,int k,int &x,int &y)
    12 {
    13     if(!now)x=y=0;
    14     else
    15     {
    16         if(t[now].v<=k)x=now,split(t[now].r,k,t[x].r,y);
    17         else y=now,split(t[now].l,k,x,t[y].l);
    18         update(now);
    19     }
    20 }
    21 int merge(int x,int y)
    22 {
    23     if(!x||!y)return x+y;
    24     if(t[x].rnd>t[y].rnd){t[x].r=merge(t[x].r,y);update(x);return x;}
    25     else{t[y].l=merge(x,t[y].l);update(y);return y;}
    26 }
    27 void insert(int &rt,int x)
    28 {
    29     int xx,yy;
    30     split(rt,a[x],xx,yy);
    31     rt=merge(merge(xx,x),yy);
    32 }
    33 void dfs(int x,int &y)
    34 {
    35     if(!x)return;
    36     dfs(t[x].l,y);dfs(t[x].r,y);
    37     t[x].l=t[x].r=0;
    38     insert(y,x);
    39 }
    40 int hebing(int x,int y)
    41 {
    42     if(t[x].s>t[y].s)swap(x,y);
    43     dfs(x,y);
    44     return y;
    45 }
    46 int getrank(int now,int k)
    47 {
    48     if(t[t[now].l].s+1==k)return now;
    49     if(t[t[now].l].s+1<k)return getrank(t[now].r,k-t[t[now].l].s-1);
    50     else return getrank(t[now].l,k);
    51 }
    52 char s[10];
    53 int main()
    54 {
    55     scanf("%d%d",&n,&m);
    56     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    57     for(int i=1;i<=n;++i)
    58     {
    59         f[i]=i;t[i].rnd=rand();t[i].s=1;t[i].v=a[i];
    60     }
    61     int x,y;
    62     for(int i=1;i<=m;++i)
    63     {
    64         scanf("%d%d",&x,&y);
    65         int fx=get(x);int fy=get(y);
    66         if(fx==fy)continue;
    67         int z=hebing(fx,fy);
    68         f[fx]=f[fy]=f[z]=z;
    69     }
    70     scanf("%d",&m);
    71     
    72     for(int i=1;i<=m;++i)
    73     {
    74         scanf("%s",s);
    75         if(s[0]=='B')
    76         {
    77             scanf("%d%d",&x,&y);
    78             int fx=get(x);int fy=get(y);
    79             if(fx==fy)continue;
    80             int z=hebing(fx,fy);
    81             f[fx]=f[fy]=f[z]=z;
    82         }
    83         else
    84         {
    85             scanf("%d%d",&x,&y);
    86             if(t[get(x)].s<y){
    87                 puts("-1");continue;
    88             }
    89             printf("%d
    ",getrank(get(x),y));
    90         }
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    Flink (一)概述
    【转】你未必知道的49个CSS知识点
    【转】清除浮动的四种方式及其原理理解
    前端知识总结
    【转】CSS为什么这么难学?方法很重要!
    【转】chrome开发者工具各种骚技巧
    【ASP.NET Core】设置Web API 响应的数据格式——Produces 特性篇
    【ASP.NET Core】绑定到 CancellationToken 对象
    【ASP.NET Core】设置 Web API 响应数据的格式——FormatFilter特性篇
    【ASP.NET Core】MVC 控制器的模型绑定(宏观篇)
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8044468.html
Copyright © 2020-2023  润新知