其实直接主席树+树上启发式合并就好了
一道54% RE率的题,我也光荣地贡献了好多发RE。。。
坑点还是有不少 比如那是数据编号。。还有就是记得重构的时候lca要清空QAQ
#include<bits/stdc++.h>
using namespace std;
const int N=8e4+2;
char B[1<<14],*S=B,*T=B;
#define gc (S==T&&(T=(S=B)+fread(B,1,1<<14,stdin),S==T)?-1:*S++)
inline int read(){
int x=0,f=1; char ch=gc;
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=gc;}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=gc;}
return x*f;
}
struct edge{
int y,nex;
}a[N<<1]; int len,fir[N];
void ins(int x,int y){
a[++len]=(edge){y,fir[x]},fir[x]=len;
}
int z[N],zl,qz[N],f[N],sz[N],fa[N][17],dep[N];
int Fa(int x){return x==f[x]?x:f[x]=Fa(f[x]);}
void merge(int x,int y){x=Fa(x),y=Fa(y),sz[y]+=sz[x],f[x]=y;}
int rt[N],lc[N*120],rc[N*120],s[N*120],tot;
void add(int &x,int y,int l,int r,int k){
x=++tot,s[x]=s[y]+1;
if(l==r)return;
int mid=(l+r)>>1; lc[x]=lc[y],rc[x]=rc[y];
if(k<=mid) add(lc[x],lc[y],l,mid,k);
else add(rc[x],rc[y],mid+1,r,k);
}
int query(int l,int r,int k,int A,int B,int C,int D){
if(l==r)return l;
int mid=(l+r)>>1,u=0;
u=s[lc[A]]+s[lc[B]]-s[lc[C]]-s[lc[D]];
if(u>=k) return query(l,mid,k,lc[A],lc[B],lc[C],lc[D]);
return query(mid+1,r,k-u,rc[A],rc[B],rc[C],rc[D]);
}
void dfs(int x,int FA){
add(rt[x],rt[FA],1,zl,qz[x]);
for(int i=1;i<17;++i)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int k=fir[x];k;k=a[k].nex){
int y=a[k].y; if(y==FA)continue;
dep[y]=dep[x]+1,fa[y][0]=x;
dfs(y,x);
}
}
int lca(int x,int y){
if(dep[x]<dep[y]) x^=y^=x^=y;
for(int i=16;~i;--i) if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=16;~i;--i) if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
void link(int x,int y){
ins(x,y),ins(y,x);
int fx=Fa(x),fy=Fa(y);
if(sz[fx]>sz[fy])
fa[y][0]=x,dep[y]=dep[x]+1,dfs(y,x);
else
fa[x][0]=y,dep[x]=dep[y]+1,dfs(x,y);
merge(x,y);
}
int main(){
int i,te=read(),n=read(),m=read(),q=read();
for(i=1;i<=n;++i) z[i]=qz[i]=read();
sort(z+1,z+1+n); zl=unique(z+1,z+1+n)-z-1;
for(i=1;i<=n;++i) qz[i]=lower_bound(z+1,z+1+zl,qz[i])-z;
for(i=1;i<=n;++i) f[i]=i,sz[i]=1;
int x,y,k;
for(i=1;i<=m;++i)
x=read(),y=read(),ins(x,y),ins(y,x),merge(x,y);
for(i=1;i<=n;++i) if(!rt[i])dep[i]=1,dfs(i,0);
int la=0,t;
while(q--){
char c=gc; while(c!='Q' && c!='L')c=gc;
x=read()^la,y=read()^la;
if(c=='Q'){
k=read()^la,t=lca(x,y);
printf("%d\n",la=z[ query(1,zl,k,rt[x],rt[y],rt[t],rt[fa[t][0]]) ]);
}
else link(x,y);
}
return 0;
}