12
4
2015
0

【bzoj3674】可持久化并查集加强版

3674: 可持久化并查集加强版

Time Limit: 15 Sec  Memory Limit: 256 MB
Submit: 1053  Solved: 381
[Submit][Status][Discuss]

Description

Description:
自从zkysb出了可持久化并查集后……
hzwer:乱写能AC,暴力踩标程
KuribohG:我不路径压缩就过了!
ndsf:暴力就可以轻松虐!
zky:……

n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0
0<n,m<=2*10^5


 

Input

 

Output

 

Sample Input

5 6
1 1 2
3 1 2
2 1
3 0 3
2 1
3 1 2

Sample Output

1
0
1

HINT

 

Source

好吧,我承认我确实打可持久化数据结构有点上瘾了,因为它的魅力着实让我欲罢不能。。。

回归本题。

此题我们只要维护每一次的并查集的fa数组,由于时间问题,我们还需要维护连通块中点的个数来按秩合并。要维护数组,我们可以用可持久化线段树来维护,线段树的叶子节点就是这个数组,这样就可以维护每次的并查集了。

代码:

 

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,opt,x,y,x1,x2,ans,cnt,root[210010];
struct node{int l,r,fa,num;}tr[15000010];
void change(int l,int r,int &p,int x,int fa,int num)
{
	tr[++cnt]=tr[p];p=cnt;
	if (l==r){tr[p].fa=fa;tr[p].num=num;return;}
	int mid=(l+r)>>1;
	if (x<=mid) change(l,mid,tr[p].l,x,fa,num);else change(mid+1,r,tr[p].r,x,fa,num);
}
int ask(int l,int r,int p,int x)
{
	if (l==r) return p;
	int mid=(l+r)>>1;
	if (x<=mid) return ask(l,mid,tr[p].l,x);else return ask(mid+1,r,tr[p].r,x);
}
int getfather(int p,int x)
{
	int t=ask(1,n,p,x);
	if (tr[t].fa==x) return t;else return getfather(p,tr[t].fa);
}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
		change(1,n,root[0],i,i,1);
	for (int i=1;i<=m;i++)
	{
		scanf("%d",&opt);
		root[i]=root[i-1];
		if (opt==1)
		{
			scanf("%d%d",&x,&y);
			x^=ans;y^=ans;
			x1=getfather(root[i],x);x2=getfather(root[i],y);
			if (tr[x1].fa==tr[x2].fa) continue;
			if (tr[x1].num>tr[x2].num) swap(x1,x2);
			change(1,n,root[i],tr[x1].fa,tr[x2].fa,0);
			change(1,n,root[i],tr[x2].fa,tr[x2].fa,tr[x2].num+tr[x1].num);
		}else
		if (opt==2)
		{
			scanf("%d",&x);
			x^=ans;
			root[i]=root[x];
		}else
		{
			scanf("%d%d",&x,&y);
			x^=ans;y^=ans;
			x1=getfather(root[i],x);x2=getfather(root[i],y);
			if (tr[x1].fa==tr[x2].fa) ans=1;else ans=0;
			printf("%d\n",ans);
		}
	}
}
Category: 可持久化线段树 | Tags: | Read Count: 291

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com