P3690 【模板】Link Cut Tree (动态树)

思路

candy
不是太掌握
也落落不太清楚
自己学习吧
lmc讲的时候睡着了

#include<bits/stdc++.h>
#define ls c[x][0]
#define rs c[x][1]
const int N=300009;
using namespace std;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int f[N],c[N][2],v[N],s[N],st[N];
bool lazy[N];
inline bool isroot(int x){
    return c[f[x]][0]==x||c[f[x]][1]==x;
}
void pushup(int x){
    s[x]=s[ls]^s[rs]^v[x];
}
void tag(int x){swap(ls,rs);lazy[x]^=1;}
void pushdown(int x){
    if(lazy[x]){
        if(ls)tag(ls);
        if(rs)tag(rs);
        lazy[x]=0;
    }
}
void rotate(int x){
    int y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
    if(isroot(y))c[z][c[z][1]==y]=x;
    c[x][!k]=y;
    c[y][k]=w;
    if(w)f[w]=y;
    f[y]=x;
    f[x]=z;
    pushup(y);
}
void splay(int x){
    int y=x,z=0;
    st[++z]=y;
    while(isroot(y))st[++z]=y=f[y];
    while(z)pushdown(st[z--]);
    while(isroot(x)){
        y=f[x];z=f[y];
        if(isroot(y)) rotate((c[y][0]==x)^(c[z][0]==y)?x:y);
        rotate(x);
    }
    pushup(x);
}
void access(int x){
    for(int y=0;x;x=f[y=x])
        splay(x),rs=y,pushup(x);
}
void makeroot(int x){
    access(x);splay(x);
    tag(x);
}
inline int findroot(int x){
    access(x);splay(x);
    while(ls)pushdown(x),x=ls;
    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&&!rs){
        f[x]=c[y][0]=0;
        pushup(y);
    }
}
int main()
{
    int n=read(),m=read();
    for(int i=1;i<=n;++i) v[i]=read();
    while(m--){
        int opt=read(),x=read(),y=read();
        if(opt==0){
           split(x,y);
           printf("%d\n",s[y]);
        } else if(opt==1){
            link(x,y);
        } else if(opt==2) {
            cut(x,y);
        } else if(opt==3) {
            splay(x);v[x]=y;
        }
    }
    return 0;
}