求调,枯了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstdlib>
using namespace std;
const long long NR=1000050;
long long n,m;
long long read(){
long long x=0,op=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')op=0;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return op?x:-x;
}
struct point{
long long val,sum;
long long fa,s[3];
long long sz;
long long spn,tag;
void newp(long long id,long long v){
val=id;sum=v;
fa=s[0]=s[1]=0;
sz=1;spn=0;tag=0;
}
}pt[NR];
long long rt=0;
void check(){
for(long long i=1;i<=n;i++){
printf("%d : fa %d, [%d-%d],val %d,sum%d,spn%d,sz%d\n",i,pt[i].fa,pt[i].s[0],pt[i].s[1],pt[i].val,pt[i].sum,pt[i].spn,pt[i].sz);
}
}
inline long long get(long long x){
if(pt[x].fa==0)return 2;
if(x==pt[pt[x].fa].s[1])return 1;
if(x==pt[pt[x].fa].s[0])return 0;
return 2;
}
void push_up(long long p){
pt[p].sz=pt[pt[p].s[0]].sz+pt[pt[p].s[1]].sz+1;
pt[p].sum=pt[pt[p].s[0]].sum^pt[pt[p].s[1]].sum^pt[p].val;
}
void push_down(long long p){
if(pt[p].spn==1){
swap(pt[p].s[0],pt[p].s[1]);
pt[pt[p].s[0]].spn^=1;
pt[pt[p].s[1]].spn^=1;
pt[p].spn=0;
}
}
void deal(long long p){
if(get(p)!=2)deal(pt[p].fa);
push_down(p);
}
namespace splay{
long long ptot=0;
void sp(long long p){
long long fa=pt[p].fa,ls=pt[p].s[0],rs=pt[p].s[1];
if(get(p)==2){
cout<<"FALSE";
}
if(get(p)==0){
pt[fa].s[0]=rs;pt[rs].fa=fa;
pt[p].fa=pt[fa].fa;pt[pt[fa].fa].s[get(fa)]=p;
pt[fa].fa=p;pt[p].s[1]=fa;
}else{
pt[fa].s[1]=ls;pt[ls].fa=fa;
pt[p].fa=pt[fa].fa;pt[pt[fa].fa].s[get(fa)]=p;
pt[fa].fa=p;pt[p].s[0]=fa;
}
push_up(fa),push_up(p);
}
void splay(long long p){
long long fa=pt[p].fa;
deal(p);
while(get(p)!=2&&get(fa)!=2){
if(get(p)==get(fa))sp(fa),sp(p);
else sp(p),sp(p);
fa=pt[p].fa;
}
if(get(p)!=2)sp(p);
}
}
long long access(long long p){
long long rs=0;
while(p!=0){
splay::splay(p);
pt[p].s[1]=rs;
push_up(p);
rs=p;p=pt[p].fa;
}
return p;
}
void makeroot(long long p){
access(p);
splay::splay(p);
pt[p].spn^=1;push_down(p);
}
void link(long long x,long long y){
makeroot(x);
long long p=y;while(pt[p].fa!=0)p=pt[p].fa;
if(p==x){
// printf("l");
return;
}
pt[x].fa=y;
push_up(y);
}
void cut(long long x,long long y){
makeroot(x);
access(y);
if(pt[x].sz!=2){
// printf("r");
return;
}
pt[x].s[1]=0;pt[y].fa=0;push_up(y);
}
long long query(long long x,long long y){
// if(x==y)return pt[x].val;
makeroot(x);
access(y);
splay::splay(y);
return pt[y].sum;
}
void mdf(long long p,long long v){
splay::splay(p);
pt[p].val=v;
push_up(p);
}
int main(){
// freopen("P3690.in","r",stdin);
// freopen("P3690.out","w",stdout);
n=read();m=read();
for(long long i=1;i<=n;i++){
pt[i].val=read();
push_up(i);
}
for(long long i=1;i<=m;i++){
long long op=read(),x=read(),y=read();
if(op==0){
printf("%lld\n",query(x,y));
}
if(op==1){
link(x,y);
}
if(op==2){
cut(x,y);
}
if(op==3){
mdf(x,y);
}
// check();
}
return 0;
}