合并线段树模板。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 char ch[2]; 5 int n,m,q,sz,f[N],root[N],sum[2000005],ls[2000005],rs[2000005],v[N],id[N]; 6 inline void update(int x){ 7 sum[x]=sum[ls[x]]+sum[rs[x]]; 8 } 9 inline int read(){ 10 int x=0,f=1; char a=getchar(); 11 while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();} 12 while(a>='0' && a<='9') x=x*10+a-'0',a=getchar(); 13 return x*f; 14 } 15 int fa(int x){ 16 return f[x]!=x?f[x]=fa(f[x]):x; 17 } 18 void inser(int& x,int l,int r,int val){ 19 x=++sz; 20 if(l==r) {sum[x]=1;return;} 21 int mid=(l+r)>>1; 22 if(val<=mid) inser(ls[x],l,mid,val); 23 else inser(rs[x],mid+1,r,val); 24 update(x); 25 } 26 int merge(int x,int y){ 27 if(!x) return y; 28 if(!y) return x; 29 ls[x]=merge(ls[x],ls[y]); 30 rs[x]=merge(rs[x],rs[y]); 31 update(x); 32 return x; 33 } 34 int query(int x,int l,int r,int k){ 35 if(l==r) return l; 36 int mid=(l+r)>>1; 37 if(sum[ls[x]]>=k) return query(ls[x],l,mid,k); 38 else return query(rs[x],mid+1,r,k-sum[ls[x]]); 39 } 40 int main(){ 41 n=read(); m=read(); 42 for(int i=1;i<=n;i++) f[i]=i; 43 for(int i=1;i<=n;i++) v[i]=read(); 44 for(int p,i=1;i<=n;i++) inser(root[i],1,n,v[i]),id[v[i]]=i; 45 for(int x,y,i=1;i<=m;i++) x=read(),y=read(),x=fa(x),y=fa(y),f[y]=x,root[x]=merge(root[x],root[y]); 46 q=read(); 47 for(int x,y,i=1;i<=q;i++){ 48 scanf("%s",ch); x=read(); y=read(); 49 if(ch[0]=='Q'){ 50 x=fa(x); 51 if(sum[root[x]]<y) {puts("-1");continue;} 52 else printf("%d\n",id[query(root[x],1,n,y)]); 53 }else{ 54 x=fa(x); y=fa(y); 55 if(x!=y) f[y]=x,root[x]=merge(root[x],root[y]); 56 } 57 } 58 return 0; 59 }