【BZOJ3674】—可持久化并查集加强版(可持久化并查集)

传送门

我还以为可持久化并查集是什么呢

可持久化并查集 = = =可持久化 + + +并查集 = = =主席树 + + +并查集

考虑到每次状态只会修改一个集合

于是就想可持久化数组一样

维护一颗主席树来维护每个点的 f a fa fa

#include<bits/stdc++.h>
using namespace std;
#define gc getchar
#define ll long long
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=gc();}
	while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48),ch=gc();}
	return res*f;
}
#undef gc
const int N=200005;
const int Log=30;
int lc[N*Log],rc[N*Log],fa[N*Log],dep[N*Log],n,m,tot,rt[N*Log];
#define mid ((l+r)>>1)
void buildtree(int &u,int l,int r){
	u=++tot;
	if(l==r){fa[u]=l;return;}
	buildtree(lc[u],l,mid),buildtree(rc[u],mid+1,r);
}
void merge(int pre,int &u,int l,int r,int pos,int f){
	u=++tot,lc[u]=lc[pre],rc[u]=rc[pre];
	if(l==r){
		fa[u]=f,dep[u]=dep[pre];return;
	}
	if(pos<=mid)merge(lc[pre],lc[u],l,mid,pos,f);
	else merge(rc[pre],rc[u],mid+1,r,pos,f);
}
void update(int u,int l,int r,int pos){
	if(l==r){dep[u]++;return;}
	if(pos<=mid)update(lc[u],l,mid,pos);
	else update(rc[u],mid+1,r,pos);
}
int query(int u,int l,int r,int pos){
	if(l==r)return u;
	if(pos<=mid)return query(lc[u],l,mid,pos);
	else return query(rc[u],mid+1,r,pos);
}
int find(int u,int pos){
	int now=query(u,1,n,pos);
	if(fa[now]==pos)return now;
	return find(u,fa[now]);
}
int main(){
	n=read(),m=read();
	buildtree(rt[0],1,n);
	for(int i=1;i<=m;i++){
		int op=read(),x=read();
		if(op==1){
			rt[i]=rt[i-1];
			int y=read();
			int f1=find(rt[i],x),f2=find(rt[i],y);
			if(fa[f1]!=fa[f2]){
				if(dep[f1]>dep[f2])swap(f1,f2);
				merge(rt[i-1],rt[i],1,n,fa[f1],fa[f2]);
				if(dep[f1]==dep[f2])update(rt[i],1,n,fa[f2]);
			}
		}
		else if(op==2)rt[i]=rt[x];
		else if(op==3){
			int y=read();
			rt[i]=rt[i-1];
			int f1=find(rt[i],x),f2=find(rt[i],y);
			if(fa[f1]==fa[f2])puts("1");
			else puts("0");
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值