作者:
dys
,
2021-01-18 22:45:42
,
阅读 11
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m;
const int N = 1e5+10;
struct node{
int s[2],p,v;
int sum,rev;
}tr[N];
int stk[N];
void pushup(int x){
tr[x].sum = tr[tr[x].s[0]].sum ^ tr[x].v ^ tr[tr[x].s[1]].sum;
}
void pushrev(int x){
swap(tr[x].s[0],tr[x].s[1]);
tr[x].rev ^= 1;
}
void pushdown(int x){
if(tr[x].rev){
pushrev(tr[x].s[0]);
pushrev(tr[x].s[1]);
tr[x].rev ^= 1;
}
}
bool isroot(int x){
return tr[tr[x].p].s[0]!=x&&tr[tr[x].p].s[1]!=x;
}
void rotate(int x){
int y = tr[x].p,z = tr[y].p;
int k = tr[y].s[1] == x;
if(!isroot(y)) tr[z].s[tr[z].s[1] == y] = x;
tr[x].p = z;
tr[y].s[k] = tr[x].s[k^1];
tr[tr[x].s[k^1]].p = y;
tr[x].s[k ^ 1] = y;
tr[y].p = x;
pushup(y);
pushup(x);
}
void splay(int x){
int top = 0,r = x;
stk[++top] = r;
while(!isroot(r)) stk[++top] = r = tr[r].p;
while(top) pushdown(stk[top--]);
while(!isroot(x)){
int y = tr[x].p,z = tr[y].p;
if(!isroot(y))
if((tr[y].s[1] == x)^(tr[z].s[1] == y)) rotate(x);
else rotate(y);
rotate(x);
}
}
void access(int x){
int z = x;
for(int y = 0;x;y = x,x = tr[x].p){
splay(x);
tr[x].s[1] = y;
pushup(x);
}
splay(z);
}
void makeroot(int x){
access(x);
pushrev(x);
}
int findroot(int x){
access(x);
while(tr[x].s[0]) pushdown(x),x = tr[x].s[0];
splay(x);
return x;
}
void split(int x,int y){
makeroot(x);
access(y);
}
void link(int x,int y){
makeroot(x);
if(findroot(y) != x) tr[x].p = y;
}
void cut(int x,int y){
makeroot(x);
if(findroot(y) == x && tr[y].p == x && !tr[y].s[0]){
tr[x].s[1] = tr[y].p = 0;
pushup(x);
}
}
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++) cin >> tr[i].v;
int op,x,y,w;
while(m--){
cin >> op;
if(op == 0){
cin >> x >> y;
split(x,y);
cout<< tr[y].sum <<endl;
}else if(op == 1){
cin >> x >> y;
link(x,y);
}else if(op == 2){
cin >> x >> y;
cut(x,y);
}else{
cin >> x >> w;
splay(x);
tr[x].v = w;
pushup(x);
}
}
return 0;
}