题目链接:https://www.luogu.org/problemnew/show/P3224
splay启发式合并模板,小splay往大splay插,感性理解,一个点最多插logn次,插一次logn,n个点,nlognlogn~
#include<bits/stdc++.h>
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
const int N = 2e5+10;
int n,m,a[N];
int fa[N],rt[N];
inline int getfa(int x){//连通性用并查集维护
return x^fa[x]?fa[x]=getfa(fa[x]):x;
}
struct Splay{
int p[N],ch[N][2];
int cnt,vl[N],idx[N],siz[N];
#define Ls(x) ch[x][0]
#define rs(x) ch[x][1]
#define maintain(x) siz[x]=siz[Ls(x)]+siz[rs(x)]+1
inline void rotate(int x){
int f=p[x],gf=p[f],tp=rs(f)==x,son=ch[x][!tp];
ch[p[son]=f][tp]=son,maintain(f);
ch[p[f]=x][!tp]=f,maintain(x);
ch[p[x]=gf][rs(gf)==f]=x;
}
inline void splay(int x,int goal,int &root){
if(x==goal)return ;
while(p[x]^goal){
if((p[p[x]]^goal)&&((rs(p[p[x]])==p[x])==(rs(p[x])==x)))rotate(p[x]);
rotate(x);
}
if(!goal)root=x;
}
inline void newnode(int x,int k,int Fa,int Idx){
idx[x]=Idx,siz[x]=1,vl[x]=k,p[x]=Fa;
}
inline void insert(int &x,int k,int Fa,int Idx,int &root){
if(!x)return newnode(x=++cnt,k,Fa,Idx),splay(x,0,root),void();
insert(ch[x][vl[x]<k],k,x,Idx,root);
}
inline int getrank(int x,int kth){
while(x){
if(siz[Ls(x)]+1==kth)return x;
if(siz[Ls(x)]+1<kth)kth-=siz[Ls(x)]+1,x=rs(x);
else x=Ls(x);
}
return -1;
}
}sp;
inline void init(){
scanf("%d%d",&n,&m);
Inc(i,1,n)scanf("%d",&a[i]);
Inc(i,1,n)fa[i]=i;
Inc(i,1,m){
int x,y;scanf("%d%d",&x,&y);
fa[getfa(x)]=getfa(y);
}
}
inline void prep(){
Inc(i,1,n){
int fx=getfa(i);
sp.insert(rt[fx],a[i],0,i,rt[fx]);
}
}
inline void Merge(int x,int &root){
if(!x)return ;
Merge(sp.Ls(x),root),Merge(sp.rs(x),root);
sp.insert(root,sp.vl[x],0,sp.idx[x],root);
}
inline void merge(int x,int y){
int fx=getfa(x),fy=getfa(y);
if(sp.siz[rt[fx]]<sp.siz[rt[fy]])swap(fx,fy);
fa[fy]=fx;
Merge(rt[fy],rt[fx]);
}
inline void query(int x,int k){
int p=sp.getrank(rt[getfa(x)],k);
if(~p)cout<<sp.idx[p]<<"\n";
else puts("-1");
}
inline void solv(){
int T;scanf("%d",&T);
while(T--){
char op=getchar();while((op^'Q')&&(op^'B'))op=getchar();
int x,k;scanf("%d%d",&x,&k);
if(op=='Q')query(x,k);
if(op=='B')merge(x,k);
}
}
int main(){
init();
prep();
solv();
return 0;
}