P3690 【模板】Link Cut Tree (动态树)
P3690 【模板】Link Cut Tree (动态树)
思路
candy
不是太掌握
也落落不太清楚
自己学习吧
lmc讲的时候睡着了
#include<bits/stdc++.h>
#define ls c[x][0]
#define rs c[x][1]
const int N=300009;
using namespace std;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int f[N],c[N][2],v[N],s[N],st[N];
bool lazy[N];
inline bool isroot(int x){
return c[f[x]][0]==x||c[f[x]][1]==x;
}
void pushup(int x){
s[x]=s[ls]^s[rs]^v[x];
}
void tag(int x){swap(ls,rs);lazy[x]^=1;}
void pushdown(int x){
if(lazy[x]){
if(ls)tag(ls);
if(rs)tag(rs);
lazy[x]=0;
}
}
void rotate(int x){
int y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
if(isroot(y))c[z][c[z][1]==y]=x;
c[x][!k]=y;
c[y][k]=w;
if(w)f[w]=y;
f[y]=x;
f[x]=z;
pushup(y);
}
void splay(int x){
int y=x,z=0;
st[++z]=y;
while(isroot(y))st[++z]=y=f[y];
while(z)pushdown(st[z--]);
while(isroot(x)){
y=f[x];z=f[y];
if(isroot(y)) rotate((c[y][0]==x)^(c[z][0]==y)?x:y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=0;x;x=f[y=x])
splay(x),rs=y,pushup(x);
}
void makeroot(int x){
access(x);splay(x);
tag(x);
}
inline int findroot(int x){
access(x);splay(x);
while(ls)pushdown(x),x=ls;
return x;
}
void split(int x,int y){
makeroot(x);
access(y);splay(y);
}
void link(int x,int y){
makeroot(x);
if(findroot(y)!=x)f[x]=y;
}
void cut(int x,int y){
makeroot(x);
if(findroot(y)==x&&f[x]==y&&!rs){
f[x]=c[y][0]=0;
pushup(y);
}
}
int main()
{
int n=read(),m=read();
for(int i=1;i<=n;++i) v[i]=read();
while(m--){
int opt=read(),x=read(),y=read();
if(opt==0){
split(x,y);
printf("%d\n",s[y]);
} else if(opt==1){
link(x,y);
} else if(opt==2) {
cut(x,y);
} else if(opt==3) {
splay(x);v[x]=y;
}
}
return 0;
}