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\n",getrank(get(x),y)); 90 } 91 } 92 return 0; 93 }
转载于:https://www.cnblogs.com/nbwzyzngyl/p/8044468.html