基本上就是模板题,没有什么好解释的
初始时是 n n n棵树,如果要动态连边的话 l i n k link link即可
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=1e9+7;
const int M=1e8+5;
const int N=1e5+5;//?????????? 4e8
struct node
{
int fa,l,r,val,sum,add;
}e[N];
int n,m;
void reverse(int p)
{
swap(e[p].l,e[p].r);
e[p].add^=1;
}
void update(int p)
{
e[p].sum=e[e[p].l].sum^e[e[p].r].sum^e[p].val;
}
bool ntroot(int p)
{
return e[e[p].fa].l==p||e[e[p].fa].r==p;
}
bool ident(int p,int f)
{
return e[f].r==p;
}
void connect(int p,int f,int s)
{
if(s==0) e[e[p].fa=f].l=p;
else e[e[p].fa=f].r=p;
}
void spread(int p)
{
if(e[p].add)
{
if(e[p].l) reverse(e[p].l);
if(e[p].r) reverse(e[p].r);
e[p].add=0;
}
}
void push(int p)
{
if(ntroot(p)) push(e[p].fa);
spread(p);
}
void rotate(int p)
{
int f=e[p].fa;
int ff=e[f].fa;
int k=ident(p,f);
if(k==0) connect(e[p].r,f,k);
else connect(e[p].l,f,k);
e[p].fa=ff;
if(ntroot(f))
{
int op=ident(f,ff);
if(op) e[ff].r=p;
else e[ff].l=p;
}
connect(f,p,k^1);
update(f);update(p);
}
void splaying(int p)
{
push(p);
while(ntroot(p))
{
int f=e[p].fa;
int ff=e[f].fa;
if(ntroot(f)) ident(f,ff)^ident(p,f)?rotate(p):rotate(f);
rotate(p);
}
}
void access(int p)
{
// cout<<p<<endl;
for(re y=0;p;p=e[y=p].fa)
{
splaying(p);
e[p].r=y;
update(p);
}
}
void mkroot(int p)
{
access(p);
splaying(p);
reverse(p);
}
int findroot(int p)
{
access(p);
splaying(p);
while(e[p].l)
{
push(p);
p=e[p].l;
}
splaying(p);
return p;
}
void link(int x,int y)
{
mkroot(x);
if(findroot(y)==x) return;
e[x].fa=y;
}
void cut(int x,int y)
{
mkroot(x);
if(findroot(y)!=x||e[y].fa!=x||e[y].l) return;
e[y].fa=e[x].r=0;
update(x);
}
void split(int x,int y)
{
mkroot(x);
access(y);
splaying(y);
}
void solve()
{
cin>>n>>m;
for(re i=1;i<=n;i++) scanf("%d",&e[i].val);
while(m--)
{
int op,x,y;
scanf("%d %d %d",&op,&x,&y);
if(op==0)
{
split(x,y);
printf("%d\n",e[y].sum);
}
if(op==1) link(x,y);
if(op==2) cut(x,y);
if(op==3)
{
splaying(x);
e[x].val=y;
update(x);
}
}
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case %d:\n",index);
solve();
// puts("");
}
return 0;
}
/*
1
6 5
0 0 0 122 499 8888
*/