在犹豫是否可以进行路径压缩中......
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
void setIO(string a){
string in=a+".in",out=a+".out";
freopen(in.c_str(),"r",stdin), freopen(out.c_str(),"w",stdout);
}
int read(){
int a;
scanf("%d",&a);
return a;
}
const int maxn=100000+3;
const int const_tree=52;
struct Node{
int fa, siz;
Node(int fa=0,int siz=0):fa(fa),siz(siz){}
}node[maxn*const_tree];
int root[maxn*const_tree];
struct Chair_Tree{
#define lson lson[o]
#define rson rson[o]
int cnt_tree;
void build(int l,int r,int &o){
if(l>r) return;
o=++cnt_tree;
if(l==r){
node[o]=Node(l,1);
return;
}
int mid=(l+r)>>1;
build(l,mid,lson[o]);
build(mid+1,r,rson[o]);
}
int insert(int l,int r,int o,int pos,Node k){
int oo=++cnt_tree;
lson[oo]=lson[o];
rson[oo]=rson[o];
if(l==r){
node[oo]=k;
return oo;
}
int mid=(l+r)>>1;
if(pos<=mid) lson[oo]=insert(l,mid,lson,pos,k);
else rson[oo]=insert(mid+1,r,rson,k);
return oo;
}
Node query(int l,int r,int o,int pos){
if(l==r) return node[o];
int mid=(l+r)>>1;
if(pos<=mid)return query(l,mid,lson,pos);
else return query(mid+1,r,rson,pos);
}
}tree;
Node find_fa(int a, int id){
Node k=tree.query(1,n,root[id],a);
if(k.fa==a) return k;
else return find_fa(k.fa, id);
}
int n,m;
void work(){
n=read(),m=read();
tree.build(1,n,root[0]);
for(int i=1;i<=m;++i){
int opt,a,b,k;
scanf("%d",&opt);
switch(opt){
case 1:{
a=read(),b=read();
Node x=find_fa(a,root[i-1]); //node of a's ancester
Node y=find_fa(b,root[i-1]); //node of b's ancester
Node A=tree.query(1,n,root[i-1],a); //node a
Node B=tree.query(1,n,root[i-1],b); //node b
if(x==y) continue;
//merge b to a
if(x.siz > y.siz){
int rt=tree.insert(1,n,root[i-1],b,Node(x.fa,B.siz));
root[i]=tree.insert(1,n,rt,a,Node())
}
else{
}
break;
}
case 2:{
k=read();
root[i]=root[k];
break;
}
case 3:{
a=read(),b=read();
break;
}
}
}
}
int main(){
setIO("input");
work();
return 0;
}