传送门
【题目分析】
emmm,先留个坑。
板子先留着。
Link和Cut的时候好神奇啊qwq。
看懂再写点。qwq
【代码~】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+10;
int n,q;
int lc[MAXN],rc[MAXN],val[MAXN];
int fa[MAXN],sum[MAXN];
int rev[MAXN];
int que[MAXN],tot;
int Read(){
int i=0,f=1;
char c;
for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-')
f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())
i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
void push_up(int root){
sum[root]=sum[lc[root]]^sum[rc[root]]^val[root];
}
void push_down(int root){
if(rev[root]){
int lson=lc[root],rson=rc[root];
rev[lson]^=1,rev[rson]^=1;
rev[root]^=1;
swap(lc[root],rc[root]);
}
}
int isroot(int x){
return lc[fa[x]]!=x&&rc[fa[x]]!=x;
}
int which(int x,int y){
return rc[y]==x;
}
void rotate(int x){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(!which(y,z))
lc[z]=x;
else
rc[z]=x;
}
if(!which(x,y)){
fa[x]=z,fa[y]=x;
fa[rc[x]]=y;
lc[y]=rc[x];
rc[x]=y;
}
else{
fa[x]=z,fa[y]=x;
fa[lc[x]]=y;
rc[y]=lc[x];
lc[x]=y;
}
push_up(y),push_up(x);
}
void splay(int x){
tot=0;
que[++tot]=x;
for(int i=x;!isroot(i);i=fa[i])
que[++tot]=fa[i];
for(int i=tot;i;--i)
push_down(que[i]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if((!which(x,y))^(!which(y,z)))
rotate(x);
else
rotate(y);
}
rotate(x);
}
}
void access(int x){
for(int t=0;x;t=x,x=fa[x]){
splay(x);
rc[x]=t;
push_up(x);
}
}
void makeroot(int x){
access(x);
splay(x);
rev[x]^=1;
}
int findroot(int x){
access(x);
splay(x);
while(lc[x]){
push_down(x);
x=lc[x];
}
return x;
}
void link(int x,int y){
makeroot(x);
if(findroot(y)!=x)
fa[x]=y;
}
void cut(int x,int y){
splay(y);
lc[y]=fa[x]=0;
push_up(y);
}
int main(){
n=Read(),q=Read();
for(int i=1;i<=n;++i){
val[i]=Read();
sum[i]=val[i];
}
while(q--){
int cz=Read();
if(cz==0){
int x=Read(),y=Read();
makeroot(x);
access(y);
splay(y);
cout<<sum[y]<<'\n';
}
if(cz==1){
int x=Read(),y=Read();
int fx=findroot(x),fy=findroot(y);
if(fx!=fy)
link(x,y);
}
if(cz==2){
int x=Read(),y=Read();
if(findroot(x)!=findroot(y))
continue;
makeroot(x);
access(y);
if(!rc[lc[y]]&&!lc[lc[y]])
cut(x,y);
}
if(cz==3){
int x=Read(),k=Read();
access(x);
splay(x);
val[x]=k;
push_up(x);
}
}
return 0;
}