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 }
原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8044468.html