Link Cut Tree(LCT)模板 [BZOJ][3282]Tree
#include<bits/stdc++.h> using namespace std; int n,m; namespace LCT { const int MAXN=3e5+233; int top,ch[MAXN][2],fa[MAXN],rev[MAXN],st[MAXN],val[MAXN],xr[MAXN]; int isroot(int x) { return ch[fa[x]][ch[fa[x]][1]==x]!=x; } void push_down(int x) { if (rev[x]) { rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,rev[x]^=1; swap(ch[x][0],ch[x][1]); } } void update(int x){ xr[x]=val[x]^xr[ch[x][0]]^xr[ch[x][1]]; } void rotate(int x) { int y=fa[x],z=fa[y],d=(ch[y][1]==x); if (!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; ch[y][d]=ch[x][d^1],fa[ch[x][d^1]]=y; ch[x][d^1]=y,fa[y]=x; update(y),update(x); } void splay(int x) { int y; st[top=1]=x; for (y=x; !isroot(y); y=fa[y]) st[++top]=fa[y]; for (y=top; y; y--) push_down(st[y]); for (; (y=fa[x])&&!isroot(x); rotate(x)) if (!isroot(y)) rotate((x==ch[y][0])^(y==ch[fa[y]][0]) ? x:y); } void access(int x){ for (int pre=0;x;pre=x,x=fa[x]) splay(x),ch[x][1]=pre,update(x); } void makeroot(int x){ access(x),splay(x),rev[x]^=1; } void link(int x,int y){ makeroot(x),fa[x]=y; } void cut(int x,int y){ makeroot(x); access(y); splay(y); if (ch[y][0]==x) ch[y][0]=fa[x]=0; } int find(int x){ access(x),splay(x); while (ch[x][0]) x=ch[x][0]; return x; } } using namespace LCT; int read(){ int x=0,f=1;char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) x=x*10+ch-48,ch=getchar(); return x*f; } int main() { n=read(),m=read(); for (int i=1;i<=n;i++) xr[i]=val[i]=read(); int opt,x,y; while (m--){ opt=read(),x=read(),y=read(); switch(opt){ case 0: makeroot(x);access(y);splay(y);printf("%d\n",xr[y]);break; case 1: if (find(x)!=find(y)) link(x,y);break; case 2: if (find(x)==find(y)) cut(x,y);break; case 3: access(x);splay(x);val[x]=y;update(x);break; } } return 0; }