【BZOJ3282】Tree (Link-Cut Tree)

来源:互联网 发布:java 互斥锁 编辑:程序博客网 时间:2024/06/07 00:35

题面

BZOJ权限题呀,良心luogu上有

题解

Link-Cut Tree班子提
最近因为NOIP考炸了
学科也炸了
时间显然没有
以后再来填LCT的坑
这种题目直接上代码了。。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<set>#include<map>#include<vector>#include<queue>using namespace std;#define RG register #define MAX 301000inline int read(){    int x=0,t=1;char ch=getchar();    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();    if(ch=='-')t=-1,ch=getchar();    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();    return x*t;}struct Node{    int v,ff,ch[2];    int rev,s;}t[MAX];int n,m,val[MAX],S[MAX],top;inline void pushup(int x){    t[x].s=t[t[x].ch[0]].s^t[t[x].ch[1]].s^t[x].v;}inline void pushdown(int x){    if(t[x].rev)    {        swap(t[x].ch[0],t[x].ch[1]);        t[t[x].ch[0]].rev^=1;        t[t[x].ch[1]].rev^=1;        t[x].rev=0;    }}inline bool isroot(int x){    return t[t[x].ff].ch[0]!=x&&t[t[x].ff].ch[1]!=x;}inline void rotate(int x){    RG int y=t[x].ff,z=t[y].ff;    RG int k=t[y].ch[1]==x;    if(!isroot(y))t[z].ch[y==t[z].ch[1]]=x;t[x].ff=z;    t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;    t[x].ch[k^1]=y;t[y].ff=x;    pushup(y);pushup(x);}void Splay(int x){    S[top=1]=x;    for(RG int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;    for(RG int i=top;i;i--)pushdown(S[i]);    while(!isroot(x))    {        RG int y=t[x].ff,z=t[y].ff;        if(!isroot(y))            (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);        rotate(x);    }}void access(int x){for(RG int y=0;x;y=x,x=t[x].ff)Splay(x),t[x].ch[1]=y,pushup(x);}void makeroot(int x){access(x);Splay(x);t[x].rev^=1;}int Findroot(int x){access(x);Splay(x);while(t[x].ch[0])x=t[x].ch[0];return x;}void split(int x,int y){makeroot(x);access(y);Splay(y);}void cut(int x,int y){split(x,y);if(t[y].ch[0]==x)t[y].ch[0]=t[x].ff=0;}void link(int x,int y){makeroot(x);t[x].ff=y;}int main(){    n=read();m=read();    for(int i=1;i<=n;++i)t[i].v=t[i].s=read();    while(m--)    {        RG int opt=read();        if(opt==0)        {            RG int x=read(),y=read();            split(x,y);            printf("%d\n",t[y].s);        }        else if(opt==1)        {            RG int x=read(),y=read();            if(Findroot(x)!=Findroot(y))                link(x,y);        }        else if(opt==2)        {            RG int x=read(),y=read();            if(Findroot(x)==Findroot(y))                cut(x,y);        }        else if(opt==3)        {            RG int x=read(),y=read();            access(x);Splay(x);t[x].v=y;pushup(x);        }    }    return 0;}
原创粉丝点击