可持久化并查集模板

可持久化并查集

#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=4e5+5;
int n,m,rt[MAXN],fa[MAXN*20],cnt,kk,dep[MAXN*20];
struct ren{
	int ch[2];
}t[MAXN*20];
int build(int p,int l,int r){
	p=++cnt;
	if(l==r){fa[p]=l;return p;}
	int mid=(l+r)>>1;
	t[p].ch[0]=build(t[p].ch[0],l,mid);t[p].ch[1]=build(t[p].ch[1],mid+1,r);
	return p;
}
int ask(int p,int l,int r,int x){
	if(l==r) return p;
	int mid=(l+r)>>1;
	if(x<=mid) return ask(t[p].ch[0],l,mid,x);
	else return ask(t[p].ch[1],mid+1,r,x);
}
int findr(int p){
	int now=ask(rt[kk],1,n,p);
//	printf("SS:%d %d %d\n",p,now,fa[now]);
	if(fa[now]!=p) return findr(fa[now]);
	else return p;
}
int D(int x){
	return dep[ask(rt[kk],1,n,x)];
}
int NEW(int x){
	int kkk=++cnt;
	t[kkk]=t[x];fa[kkk]=fa[x];
	return kkk;
}
int update(int p,int l,int r,int x,int y,bool f){
	int now=NEW(p);
	if(l==r){
		if(!f) fa[now]=y;
		else dep[now]=y;
		return now;
	}
	int mid=(l+r)>>1;
	if(x<=mid) t[now].ch[0]=update(t[p].ch[0],l,mid,x,y,f);
	else t[now].ch[1]=update(t[p].ch[1],mid+1,r,x,y,f);
	return now;
}
void merge(int x,int y){
	int z=max(D(x)+1,D(y));
	kk++;
	rt[kk]=update(rt[kk-1],1,n,x,y,0);
	rt[kk]=update(rt[kk],1,n,y,z,1);
}
void comb(int x,int y)
{
	int fx=findr(x),fy=findr(y);
	if(fx==fy){
		kk++;rt[kk]=NEW(rt[kk-1]);return;
	}
	if(D(fx)<=D(fy)) merge(fx,fy);
	else merge(fy,fx);
}
int main(){
	scanf("%d%d",&n,&m);
	rt[kk]=build(1,1,n);
	for(int i=1;i<=m;i++){
		int op;
		scanf("%d",&op);
		if(op==1){
			int x,y;scanf("%d%d",&x,&y);comb(x,y);
		}
		if(op==2){
			int x;scanf("%d",&x);kk++;rt[kk]=rt[x];
		}
		if(op==3){
//			printf("CAO:%d %d\n",kk,rt[kk]);
			int x,y;scanf("%d%d",&x,&y);
			if(findr(x)==findr(y)) printf("1\n");
			else printf("0\n");
			kk++;
			rt[kk]=NEW(rt[kk-1]);
		}
//		printf("YES!!!!!!!:%d\n",rt[1]);
	}
}
posted @ 2022-03-01 16:07  StranGePants  阅读(23)  评论(0编辑  收藏  举报