可持久化并查集模板
可持久化并查集
#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]);
}
}
本文来自博客园,作者:{StranGePants},转载请注明原文链接:https://www.cnblogs.com/StranGePants/p/15950813.html