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;
}

 

posted @ 2018-08-24 12:40  QingCai_DCF  阅读(139)  评论(0编辑  收藏  举报