学了一天LCT,还是不太明白,打(抄)了一个模板,先存着。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#define maxn 300005
using namespace std;
void read(int &a)
{
a=0;char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
{
a*=10;a+=c-'0';
c=getchar();
}
}
int fa[maxn],ch[maxn][2];
int val[maxn],d[maxn];
bool rev[maxn];
void up(int x)
{val[x]=val[ch[x][0]]^val[ch[x][1]]^d[x];}
bool isroot(int x)
{return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void down(int x)
{
if(rev[x])
{
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
rev[x]=0;
}
}
bool dir(int x)
{return x==ch[fa[x]][1];}
void rotate(int x)
{
int y=fa[x];
int z=fa[y];
bool b=dir(x);
int a=ch[x][!b];
if(!isroot(y))
ch[z][dir(y)]=x;
fa[x]=z;fa[y]=x;
ch[x][!b]=y;
ch[y][b]=a;
if(a) fa[a]=y;
up(y);up(x);
}
stack<int> S;
void splay(int x)
{
S.push(x);
for(int i=x;!isroot(i);i=fa[i])
S.push(fa[i]);
while(!S.empty())
{
int v=S.top();
S.pop();down(v);
}
while(!isroot(x))
{
int y=fa[x];
if(isroot(y)) rotate(x);
else
{
bool b=dir(x),c=dir(y);
if(b^c) {rotate(x);rotate(x);}
else {rotate(y);rotate(x);}
}
}
}
void access(int x)
{
int t=0;
while(x){
splay(x);ch[x][1]=t;up(x);
t=x;x=fa[x];
}
}
void make_root(int x)
{access(x);splay(x);rev[x]^=1;}
void link(int u,int v)
{make_root(u);fa[u]=v;}
void cut(int x,int y)
{
make_root(x);access(y);splay(y);
if(ch[y][0]==x) ch[y][0]=fa[x]=0,up(y);
}
int find(int x)
{
access(x);splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}
int main()
{
int n,q;
read(n);read(q);
int op,x,y;
for(int i=1;i<=n;i++)
read(d[i]);
for(int i=1;i<=q;i++)
{
read(op);read(x);read(y);
if(op==0)
{
int ans=0;
make_root(x);access(y);splay(y);
printf("%d\n",val[y]);
}
if(op==1)
if(find(x)!=find(y))link(x,y);
if(op==2)
if(find(x)==find(y))cut(x,y);
if(op==3)
{
splay(x);d[x]=y;up(x);
}
}
}