可持久化并查集=可持久化数组=可持久化线段树.
AC code:
#include <cstdio>
const int N=8000010;
int n,m,p_tot,last_ans;
struct nod{
int l,r,val,num;
nod *lc,*rc;
}pool[N];
struct Segtree{
nod *root[N];
Segtree(){
build(&root[0],1,n);
for(int i=1;i<=m;i++) newnod(&root[i],1,n,0,i);
}
void build(nod **p,int L,int R){
newnod(p,L,R,L,0);
if(L==R) return ;
int M=(L+R)>>1;
build(&(*p)->lc,L,M);
build(&(*p)->rc,M+1,R);
}
void newnod(nod **p,int l,int r,int val,int num){
*p=&pool[p_tot++];
(*p)->l=l;(*p)->r=r;(*p)->val=val;(*p)->num=num;
}
int getval(nod *p,int pos){
if(p->l==p->r) return p->val;
int M=(p->l+p->r)>>1;
if(pos<=M) return getval(p->lc,pos);
return getval(p->rc,pos);
}
void modify(nod **p,int num,int pos,int v){
if((*p)->num!=num){
nod *lc=(*p)->lc,*rc=(*p)->rc;
newnod(p,(*p)->l,(*p)->r,(*p)->val,num);
(*p)->lc=lc;(*p)->rc=rc;
}
if((*p)->l==(*p)->r){
(*p)->val=v;
return ;
}
int M=((*p)->l+(*p)->r)>>1;
if(pos<=M) modify(&(*p)->lc,num,pos,v);
else modify(&(*p)->rc,num,pos,v);
}
int find(int num,int x){
int y=getval(root[num],x);
if(y==x) return x;
int f=find(num,y);
modify(&root[num],num,x,f);
return f;
}
void merge(int num,int a,int b){
root[num]->lc=root[num-1]->lc;root[num]->rc=root[num-1]->rc;
modify(&root[num],num,find(num,a),find(num,b));
}
void back(int num,int k){
root[num]->lc=root[k]->lc;root[num]->rc=root[k]->rc;
}
void query(int num,int a,int b){
root[num]->lc=root[num-1]->lc;root[num]->rc=root[num-1]->rc;
if(find(num,getval(root[num],a))==find(num,getval(root[num],b))){
last_ans=1;
printf("1\n");
}
else{
last_ans=0;
printf("0\n");
}
}
};
int main(){
scanf("%d%d",&n,&m);
Segtree T;
for(int i=1;i<=m;i++){
int t,k,a,b;
scanf("%d",&t);
if(t==1){
scanf("%d%d",&a,&b);
a^=last_ans;b^=last_ans;
T.merge(i,a,b);
}
else if(t==2){
scanf("%d",&k);
k^=last_ans;
T.back(i,k);
}
else{
scanf("%d%d",&a,&b);
a^=last_ans;b^=last_ans;
T.query(i,a,b);
}
}
return 0;
}