为了方便自己阅读,将部分代码贴到 优快云 上。
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1e5+5;
int n, m;
struct Node{
int s[2], p, v;
int sum, rev;
}tr[N];
int stk[N];
void pushrev(int x){
swap(tr[x].s[0], tr[x].s[1]);
tr[x].rev^=1;
}
void pushup(int x){
tr[x].sum=tr[tr[x].s[0]].sum^tr[x].v^tr[tr[x].s[1]].sum;
}
void pushdown(int x){
if(tr[x].rev){
pushrev(tr[x].s[0]), pushrev(tr[x].s[1]);
tr[x].rev=0;
}
}
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[tr[x].s[k^1]].p=y, tr[y].s[k]=tr[x].s[k^1];
tr[y].p=x, tr[x].s[k^1]=y;
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){ // 建立从原树的根到 x 的路径,同时 x 成为(splay)根节点。
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){ // x 成为原树的根节点
access(x);
pushrev(x);
}
int findroot(int x){ // 找到 x 所在原树的根节点,再将原树根节点转到 splay 的根节点
access(x);
while(tr[x].s[0]) pushdown(x), x=tr[x].s[0];
splay(x);
return x;
}
void split(int x, int y){ // x, y 路径用 splay 维护起来,splay 根为 y
makeroot(x);
access(y);
}
void link(int x, int y){ // 若 x, y 不连通,连边
makeroot(x);
if(findroot(y)!=x) tr[x].p=y;
}
void cut(int x, int y){ // x, y 间若直接连边,删除之
makeroot(x); // 让 y 一定是 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++) read(tr[i].v);
while(m--){
int op, x, y; read(op), read(x), read(y);
if(op==0){
split(x, y);
cout<<tr[y].sum<<'\n';
}
else if(op==1) link(x, y);
else if(op==2) cut(x, y);
else if(op==3){
splay(x);
tr[x].v=y;
pushup(x); // ?
}
}
return 0;
}