题解网上都有。。。
注意主席树的写法吧。。。我这样写可能空间小点吧。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 80050 #define maxe 200050 using namespace std; int testcase,n,m,q,lastans=0,father[maxv],size[maxv],dis[maxv],anc[maxv][20],g[maxv],nume=1,val[maxv],hash[maxv];; int root[maxv],ls[maxv*50],rs[maxv*50],sum[maxv*50],x,y,k; char type[4]; int tot=0,cnt=0,lab,times=0,vis[maxv]; struct edge { int v,nxt; }e[maxe]; void addedge(int u,int v) { e[++nume].v=v;e[nume].nxt=g[u]; g[u]=nume; } int getfather(int x) { if (father[x]!=x) father[x]=getfather(father[x]); return father[x]; } void build(int pre,int &now,int left,int right,int pos) { if (!now) now=++tot;sum[now]=sum[pre]+1; if (left==right) return; int mid=(left+right)>>1; if (pos<=mid) {build(ls[pre],ls[now],left,mid,pos);rs[now]=rs[pre];} else {build(rs[pre],rs[now],mid+1,right,pos);ls[now]=ls[pre];} } void dfs1(int x) { father[x]=lab;vis[x]=1;size[lab]++; build(root[anc[x][0]],root[x],1,n,val[x]); for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v==anc[x][0]) continue; dis[v]=dis[x]+1;anc[v][0]=x; for (int e=1;e<=19;e++) anc[v][e]=anc[anc[v][e-1]][e-1]; dfs1(v); } } void dfs2(int x) { build(root[anc[x][0]],root[x],1,n,val[x]); for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v==anc[x][0]) continue; dis[v]=dis[x]+1;anc[v][0]=x; for (int e=1;e<=19;e++) anc[v][e]=anc[anc[v][e-1]][e-1]; dfs2(v); } } int lca(int x,int y) { if (dis[x]<dis[y]) swap(x,y); for (int e=19;e>=0;e--) { if (dis[anc[x][e]]>=dis[y] && anc[x][e]) x=anc[x][e]; } if (x==y) return x; for (int e=19;e>=0;e--) { if (anc[x][e]!=anc[y][e]) { x=anc[x][e]; y=anc[y][e]; } } return anc[x][0]; } int ask(int t1,int t2,int t3,int t4,int left,int right,int k) { if (left==right) return left; int r=sum[ls[t1]]+sum[ls[t2]]-sum[ls[t3]]-sum[ls[t4]]; int r1=sum[ls[t1]],r2=sum[ls[t2]],r3=sum[ls[t3]],r4=sum[ls[t4]]; int mid=(left+right)>>1; if (k<=r) return ask(ls[t1],ls[t2],ls[t3],ls[t4],left,mid,k); else return ask(rs[t1],rs[t2],rs[t3],rs[t4],mid+1,right,k-r); } void link(int x,int y) { int f1=getfather(x),f2=getfather(y); if (size[f1]>size[f2]) {swap(f1,f2);swap(x,y);} father[f1]=f2;size[f2]+=size[f1]; dis[x]=dis[y]+1;anc[x][0]=y;for (int e=1;e<=19;e++) anc[x][e]=anc[anc[x][e-1]][e-1]; dfs2(x); } int main() { scanf("%d",&testcase); scanf("%d%d%d",&n,&m,&q); for (int i=1;i<=n;i++) { scanf("%d",&val[i]);hash[++cnt]=val[i]; father[i]=i; } for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); addedge(x,y);addedge(y,x); } sort(hash+1,hash+cnt+1);cnt=unique(hash+1,hash+cnt+1)-hash-1; for (int i=1;i<=n;i++) val[i]=lower_bound(hash+1,hash+cnt+1,val[i])-hash; times++; for (int i=1;i<=n;i++) { if (vis[i]) continue; lab=i;dfs1(i); } for (int i=1;i<=q;i++) { scanf("%s",&type); if (type[0]=='Q') { scanf("%d%d%d",&x,&y,&k); x^=lastans;y^=lastans;k^=lastans; int t=lca(x,y); lastans=hash[ask(root[x],root[y],root[t],root[anc[t][0]],1,n,k)]; printf("%d\n",lastans); } else { scanf("%d%d",&x,&y); x^=lastans;y^=lastans; link(x,y);addedge(x,y);addedge(y,x); } } return 0; }