洛谷 P3402 - 可持久化并查集

版权声明:欢迎随便转载。 https://blog.csdn.net/a1214034447/article/details/88081197

题目链接:https://www.luogu.org/problemnew/show/P3402

解题思路:

可持久化并查集也就是可持续化线段树 + 并查集 == 主席树  + 并查集

像我们平常做的并查集都是路径压缩,但因为要保证可持续化,所以信息不能改变,所以我们采用启发式合并来合并集合。

启发式合并的树最高深度不会超过log(n)+1。因为深度为2的树需要两个点,那么深度为3的需要两个深度为2的也就是2*2==4个点。所以2^n次方个点最深可以到log(n)+1。

所以主席树每个点就需要维护他的父亲和它为根的树的深度。而且只需要维护区间为1的节点就可以了。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define lson l,mid,s[rt].ls
#define rson mid+1,r,s[rt].rs
using namespace std;
typedef long long ll;
const int mx = 2e5 + 10;
const int mod = 1e9+7;
const ll INF = -1e16;
int n,m,siz,root[mx];
struct node
{
	int f,dep;
	int ls,rs;	
}s[mx*30]; 
void build(int l,int r,int& rt)
{
	rt = siz++;
	if(l==r){
		s[rt].f = l;
		return ;
	}
	int mid = (l+r)>>1;
	build(lson);build(rson);
}
node query(int l,int r,int rt,int p)
{
	if(l==r) return s[rt];
	int mid = (l+r) >> 1;
	if(p<=mid) return query(lson,p);
	return query(rson,p);
}
node find(int rt,int x)
{
	while(1){
		node now = query(1,n,rt,x);
		if(now.f == x) return now;
		x = now.f;
	}
}
void merge(int l,int r,int& rt,int x,int p,int fa)
{
	rt = siz++;
	s[rt] = s[x];
	if(l==r){
		s[rt].f = fa;
		return ;
	}
	int mid = (l+r)>>1;
	if(p<=mid) merge(lson,s[x].ls,p,fa);
	else merge(rson,s[x].rs,p,fa);
}
void add(int l,int r,int rt,int p)
{
	if(l==r){
		s[rt].dep++;
		return ;
	}
	int mid = (l+r)>>1;
	if(p<=mid) add(lson,p);
	else add(rson,p);
}
void update(int a,int b,int i)
{
	node vx = find(root[i-1],a);
	node vy = find(root[i-1],b);
	if(vx.f==vy.f) return ;
	if(vx.dep>vy.dep) swap(vx,vy);
	merge(1,n,root[i],root[i-1],vx.f,vy.f);
	if(vx.dep==vy.dep) add(1,n,root[i],vy.f);
}
int main()
{
	scanf("%d%d",&n,&m);
	build(1,n,root[0]);
	for(int i=1;i<=m;i++){
		int c,a,b;
		scanf("%d",&c);
		if(c==1){
			scanf("%d%d",&a,&b);
			root[i] = root[i-1];
			update(a,b,i);
		}else if(c==2){
			scanf("%d",&a);
			root[i] = root[a];
		}else{
			root[i] = root[i-1];
			scanf("%d%d",&a,&b);
			puts(find(root[i],a).f==find(root[i],b).f?"1":"0");
		}
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1214034447/article/details/88081197