LCT板子

粘板子:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 300050;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
int n,m,val[N];
struct LCT
{
    int fa[N],ch[N][2],w[N],v[N];
    bool res[N];
    inline void rever(int u){swap(ch[u][0],ch[u][1]);res[u]^=1;}
    inline bool isroot(int u){return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;}
    inline void update(int u){w[u]=w[ch[u][0]]^w[ch[u][1]]^v[u];}
    inline void pushdown(int u)
    {
        if(!u)return ;
        if(res[u])
        {
            rever(ch[u][0]);
            rever(ch[u][1]);
            res[u]=0;
        }
    }
    void rotate(int x)
    {
        int y = fa[x],z = fa[y],k = (ch[y][1]==x);
        if(!isroot(y))ch[z][ch[z][1]==y]=x;fa[x] = z;
        ch[y][k] = ch[x][!k],fa[ch[x][!k]] = y;
        ch[x][!k] = y,fa[y] = x;
        update(y),update(x);
    }
    void down(int x)
    {
        if(!isroot(x))down(fa[x]);
        pushdown(x);
    }
    void splay(int x)
    {
        down(x);
        while(!isroot(x))
        {
            int y = fa[x],z = fa[y];
            if(!isroot(y))
                (ch[z][1]==y)^(ch[y][1]==x)?rotate(x):rotate(y);
            rotate(x);
        }
    }
    void access(int x)
    {
        int y = 0;
        while(x)
        {
            splay(x);ch[x][1]=y;
            update(x);y=x,x=fa[x];
        }
    }
    void mtr(int x)
    {
        access(x);
        splay(x);
        rever(x);
    }
    int get_root(int x)
    {
        access(x);
        splay(x);
        while(ch[x][0])x=ch[x][0];
        return x;
    }
    void link(int x,int y)
    {
        mtr(x);
        if(get_root(y)!=x)fa[x]=y;
    }
    void cut(int x,int y)
    {
        mtr(x);
        access(y),splay(y);
        if(ch[y][0]==x)
        {
            ch[y][0]=fa[x]=0;
            update(y);
        }
    }
    void insert(int x,int y)
    {
        splay(x);
        v[x]=y;
        update(x);
    }
    int query(int x,int y)
    {
        mtr(x);
        access(y);
        splay(y);
        return w[y];
    }
}tr;
int main()
{
    read(n),read(m);
    for(int i=1;i<=n;i++)read(val[i]),tr.v[i]=tr.w[i]=val[i];
    for(int op,x,y,i=1;i<=m;i++)
    {
        read(op),read(x),read(y);
        if(op==0)printf("%d\n",tr.query(x,y));
        else if(op==1)tr.link(x,y);
        else if(op==2)tr.cut(x,y);
        else tr.insert(x,y);
    }
    return 0;
}
View Code

 

posted @ 2019-07-10 09:16  LiGuanlin  阅读(330)  评论(0编辑  收藏  举报