Analysis
裸的线段树合并板子题
Code
#include<bits/stdc++.h>
#define in read()
#define re register
using namespace std;
inline int read(){
char ch;int f=1,res=0;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^48);
ch=getchar();
}
return f==1?res:-res;
}
const int N=1e5+10;
int n,m,cnt=0,idx[N];
int rank[N],rt[N],fa[N];
int lc[N*18],rc[N*18],sze[N*18];
inline void build(int &k,int l,int r,int pos){
k=++cnt;
if(l==r) { sze[k]++;return; }
int mid=l+r>>1;
if(pos<=mid) build(lc[k],l,mid,pos);
else build(rc[k],mid+1,r,pos);
sze[k]=sze[lc[k]]+sze[rc[k]];
}
inline int merge(int x,int y){
if(!x||!y) return x+y;
sze[x]+=sze[y];
lc[x]=merge(lc[x],lc[y]);
rc[x]=merge(rc[x],rc[y]);
return x;
}
inline int query(int k,int l,int r,int rk){
if(l==r) return l;
int mid=l+r>>1;
if(rk>sze[lc[k]]) return query(rc[k],mid+1,r,rk-sze[lc[k]]);
else return query(lc[k],l,mid,rk);
}
inline int getfa(int u){
return u==fa[u]?fa[u]:fa[u]=getfa(fa[u]);
}
int main(){
n=in;m=in;
for(re int i=1;i<=n;++i){
rank[i]=in;fa[i]=i;idx[rank[i]]=i;
build(rt[i],1,n,rank[i]);
}
for(re int i=1;i<=m;++i){
int a=in,b=in;
int f=getfa(a),fb=getfa(b);
if(f==fb) continue;
rt[f]=merge(rt[f],rt[fb]);
fa[fb]=f;
}
char op[2];
int q=in;
while(q--){
scanf("%s",op);
int x=in,y=in;
if(op[0]=='B'){
int f=getfa(x),fb=getfa(y);
if(f==fb) continue;
rt[f]=merge(rt[f],rt[fb]);
fa[fb]=f;
}
else{
int f=getfa(x);
if(sze[rt[f]]<y) printf("-1\n");
else printf("%d\n",idx[query(rt[f],1,n,y)]);
}
}
return 0;
}