被安利了一道奇怪的主席树……
于是跪着写可持久化数组&&可持久化并查集
【听说不会卡我就直接随机合并23333
#include<bits/stdc++.h>
#define MAXN 200057
using namespace std; int n,m;
int leftson[MAXN<<4],rightson[MAXN<<4],dt[MAXN<<4];
int root[MAXN] , cnt_node=0;
void build(int now,int l,int r){
if(l==r) return dt[now]=l, void();
int mid=(l+r)>>1;
build(leftson[now]=++cnt_node,l,mid);
build(rightson[now]=++cnt_node,mid+1,r);
}
int inqry(int now,int l,int r,int pos){
if(l==r) return dt[now];
int mid=(l+r)>>1;
if(pos<=mid) return inqry(leftson[now],l,mid,pos);
else return inqry(rightson[now],mid+1,r,pos);
}
void add_str(int pre,int &now,int l,int r,int pos,int v){
now=++cnt_node;
if(l==r) return dt[now]=v, void();
leftson[now]=leftson[pre] , rightson[now]=rightson[pre];
int mid=(l+r)>>1;
if(pos<=mid) add_str(leftson[pre],leftson[now],l,mid,pos,v);
else add_str(rightson[pre],rightson[now],mid+1,r,pos,v);
}
int findfather(int i,int x){
int fnow=inqry(root[i],1,n,x);
return fnow==x?fnow:findfather(i,fnow);
}
void merge(int i,int x,int y){
int fx=findfather(i,x) , fy=findfather(i,y);
if(rand()&1) add_str(root[i-1],root[i],1,n,fx,fy);
else add_str(root[i-1],root[i],1,n,fy,fx);
}
int opt,read_x,read_y,read_k;
int main(){
int z=1<<25;
__asm__("movl %0,%%esp\n"::"r"(new char[z]+z));
scanf("%d%d",&n,&m);
srand(n);
build(root[0]=++cnt_node,1,n);
for(int i=1;i<=m;++i){
scanf("%d",&opt);
if(opt==1){
root[i]=root[i-1];
scanf("%d%d",&read_x,&read_y);
merge(i,read_x,read_y);
}
if(opt==2){
scanf("%d",&read_k);
root[i]=root[read_k];
}
if(opt==3){
root[i]=root[i-1];
scanf("%d%d",&read_x,&read_y);
int fx=findfather(i,read_x) , fy=findfather(i,read_y);
if(fx==fy) puts("1");
else puts("0");
}
}
return 0;
}