AC日记——【模板】Link Cut Tree 洛谷 P3690

【模板】Link Cut Tree

 

思路:

  LCT模板;

 

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 300005
int n,m,val[maxn];
int top,ch[maxn][2],f[maxn],xr[maxn],q[maxn],rev[maxn];
inline void in(int &now)
{
    int if_z=1;now=0;
    char Cget=getchar();
    while(Cget>'9'||Cget<'0')
    {
        if(Cget=='-') if_z=-1;
        Cget=getchar();
    }
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
    now*=if_z;
}
inline void updata(int now)
{
    xr[now]=xr[ch[now][0]]^xr[ch[now][1]]^val[now];
}
inline void downdata(int now)
{
    int l=ch[now][0],r=ch[now][1];
    if(rev[now])
    {
        rev[l]^=1,rev[r]^=1,rev[now]^=1;
        swap(ch[now][0],ch[now][1]);
    }
}
inline bool isroot(int now)
{
    return ch[f[now]][0]!=now&&ch[f[now]][1]!=now;
}
inline void rotate(int now)
{
    int fa=f[now],ffa=f[fa],l,r;
    if(ch[fa][0]==now) l=0;else l=1;r=l^1;
    if(!isroot(fa))
    {
        if(ch[ffa][0]==fa) ch[ffa][0]=now;
        else ch[ffa][1]=now;
    }
    f[now]=ffa,f[fa]=now,f[ch[now][r]]=fa;
    ch[fa][l]=ch[now][r],ch[now][r]=fa;
    updata(fa),updata(now);
}
inline void splay(int now)
{
    top=1,q[top]=now;
    for(int i=now;!isroot(i);i=f[i]) q[++top]=f[i];
    for(int i=top;i;i--) downdata(q[i]);
    while(!isroot(now))
    {
        int fa=f[now],ffa=f[fa];
        if(!isroot(fa))
        {
            if((ch[fa][0]==now)^(ch[ffa][0]==fa)) rotate(now);
            else rotate(fa);
        }
        rotate(now);
    }
}
void access(int now)
{
    for(int t=0;now;t=now,now=f[now])
    {
        splay(now);
        ch[now][1]=t;
        updata(now);
    }
}
void makeroot(int now)
{
    access(now);
    splay(now);
    rev[now]^=1;
}
int find(int now)
{
    access(now);
    splay(now);
    while(ch[now][0]) now=ch[now][0];
    return now;
}
void split(int x,int y)
{
    makeroot(x);
    access(y);
    splay(y);
}
void cut(int x,int y)
{
    split(x,y);
    if(ch[y][0]==x) ch[y][0]=0,f[x]=0;
}
void link(int x,int y)
{
    makeroot(x);
    f[x]=y;
}
int main()
{
    in(n),in(m);int op,x,y,xx,yy;
    for(int i=1;i<=n;i++) in(val[i]),xr[i]=val[i];
    while(m--)
    {
        in(op);
        if(op==0)
        {
            in(x),in(y),split(x,y);
            printf("%d\n",xr[y]);
        }
        if(op==1)
        {
            in(x),in(y),xx=find(x),yy=find(y);
            if(xx!=yy) link(x,y);
        }
        if(op==2)
        {
            in(x),in(y),xx=find(x),yy=find(y);
            if(xx==yy) cut(x,y);
        }
        if(op==3)
        {
            in(x),in(y);
            access(x);
            splay(x);
            val[x]=y;
            updata(x);
        }
    }
}

 

posted @ 2017-06-11 06:44  IIIIIIIIIU  阅读(230)  评论(0编辑  收藏  举报