BZOJ3674 可持久化并查集加强版 可持久化 并查集

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ3674


题意概括

n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

0<n,m<=2*10^4


题解

  上板子


代码

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=200005;
bool isd(char ch){
	return '0'<=ch&&ch<='9';
}
void read(int &x){
	x=0;
	char ch=getchar();
	while (!isd(ch))
		ch=getchar();
	while (isd(ch))
		x=x*10+ch-48,ch=getchar();
}
int n,m,size,root[N],fa[N*50],ls[N*50],rs[N*50],depth[N*50];
int build(int L,int R){
	int rt=++size;
	if (L==R){
		fa[rt]=L,depth[rt]=0;
		return rt;
	}
	int mid=(L+R)>>1;
	ls[rt]=build(L,mid);
	rs[rt]=build(mid+1,R);
	return rt;
}
int query(int rt,int le,int ri,int pos){
	if (le==ri)
		return rt;
	int mid=(le+ri)>>1;
	if (pos<=mid)
		return query(ls[rt],le,mid,pos);
	else
		return query(rs[rt],mid+1,ri,pos);
}
void Modify(int prt,int &rt,int le,int ri,int pos,int val){
	rt=++size;
	if (le==ri){
		fa[rt]=val;
		depth[rt]=depth[prt];
		return;
	}
	ls[rt]=ls[prt],rs[rt]=rs[prt];
	int mid=(le+ri)>>1;
	if (pos<=mid)
		Modify(ls[prt],ls[rt],le,mid,pos,val);
	else
		Modify(rs[prt],rs[rt],mid+1,ri,pos,val);
}
void add(int rt,int le,int ri,int pos){
	if (le==ri){
		depth[rt]++;
		return;
	}
	int mid=(le+ri)>>1;
	if (pos<=mid)
		add(ls[rt],le,mid,pos);
	else
		add(rs[rt],mid+1,ri,pos);
}
int find(int rt,int pos){
	int p=query(rt,1,n,pos);
	if (pos==fa[p])
		return p;
	return find(rt,fa[p]);
}
int main(){
	size=0;
	read(n),read(m);
	root[0]=build(1,n);
	int lastans=0;
	for (int i=1;i<=m;i++){
		int op,a,b;
		root[i]=root[i-1];
		read(op),read(a);
		a^=lastans;
		if (op==1){
			read(b);
			b^=lastans;
			a=find(root[i],a),b=find(root[i],b);
			if (fa[a]==fa[b])
				continue;
			if (depth[a]>depth[b])
				swap(a,b);
			Modify(root[i-1],root[i],1,n,fa[a],fa[b]);
			if (depth[a]==depth[b])
				add(root[i],1,n,fa[b]);
		}
		else if (op==2)
			root[i]=root[a];
		else {
			root[i]=root[i-1];
			read(b);
			b^=lastans;
			a=find(root[i],a),b=find(root[i],b);
			printf("%d\n",lastans=fa[a]==fa[b]);
		}
	}
	return 0;
} 

  

 

posted @ 2017-12-11 10:47  zzd233  阅读(200)  评论(0编辑  收藏  举报