题面
https://www.luogu.org/problem/P3690
题解
#include<cstdio> #include<iostream> using namespace std; int f[300050],ch[300050][2]; int s[300050],v[300050]; int stk[300050]; bool r[300050]; int n,m; bool opt(int x) { return ch[f[x]][1]==x; } bool notroot(int x) { return ch[f[x]][0]==x || ch[f[x]][1]==x; } void pushup(int x) { s[x]=s[ch[x][0]]^s[ch[x][1]]^v[x]; } void pushr(int x) { if (!r[x]) return; r[x]=false; swap(ch[x][0],ch[x][1]); r[ch[x][0]]^=1; r[ch[x][1]]^=1; } void rotate(int x) { int y=f[x],z=f[y],s=opt(x); if (notroot(y)) ch[z][opt(y)]=x; f[x]=z; ch[y][s]=ch[x][1^s]; if (ch[x][1^s]) f[ch[x][1^s]]=y; ch[x][1^s]=y; f[y]=x; pushup(y); pushup(x); } void splay(int x) { int y=x,t=0; while(notroot(y)) stk[t++]=y,y=f[y]; stk[t]=y; while (t>=0) pushr(stk[t]),t--; while (notroot(x)) { if (!notroot(f[x])) rotate(x); else { if (opt(x)==opt(f[x]) && notroot(f[x])) rotate(f[x]),rotate(x); else rotate(x),rotate(x); } } } void access(int x) { int y=0; while (x) { splay(x); ch[x][1]=y;pushup(x); y=x;x=f[x]; } } void makeroot(int x) { access(x); splay(x); r[x]^=1; pushr(x); } int findroot(int x) { access(x); splay(x); while (ch[x][0]) pushr(x),x=ch[x][0]; return x; } void split(int x,int y) { makeroot(x); access(y); splay(y); } void link(int x,int y) { makeroot(x); if (findroot(y)!=x) f[x]=y; } void cut(int x,int y) { makeroot(x); if (findroot(y)==x && f[x]==y && !ch[x][1]) { f[x]=ch[y][0]=0; pushup(y); } } int main(){ int i,op,x,y; scanf("%d %d",&n,&m); for (i=1;i<=n;i++) scanf("%d",&v[i]); for (i=1;i<=m;i++) { scanf("%d %d %d",&op,&x,&y); if (op==0) split(x,y),pushup(y),printf("%d ",s[y]); else if (op==1) link(x,y); else if (op==2) cut(x,y); else splay(x),v[x]=y; } return 0; }