zoukankan      html  css  js  c++  java
  • 【BZOJ3673/3674】可持久化并查集/可持久化并查集加强版 可持久化线段树

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

    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

    题解:要实现可持久化并查集,只需实现可持久化数组,要实现可持久化数组,只能用可持久化线段树QAQ

    具体方法是,让可持久化线段树的叶子节点储存并查集的fa,siz信息,然后每次查询,更新都在可持久化线段树上完成。回到之前的状态只需要调用之前的树根就行了。此外不用路径压缩。

    bz3674:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int maxn=200010;
    struct sag
    {
    	int ls,rs,siz,fa;
    }s[maxn*50];
    int n,m,tot,now,ans;
    int rt[maxn<<1],to[maxn];
    int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void insert(int x,int &y,int l,int r,int pos,int a,int b)
    {
    	if(pos>r)	return ;
    	y=++tot;
    	if(l==r)
    	{
    		s[y].siz=a,s[y].fa=b;
    		return ;
    	}
    	int mid=l+r>>1;
    	if(pos<=mid)	s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,pos,a,b);
    	else	s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,pos,a,b);
    }
    int query(int l,int r,int x,int pos)
    {
    	if(l==r)	return x;
    	int mid=l+r>>1;
    	if(pos<=mid)	return query(l,mid,s[x].ls,pos);
    	else	return query(mid+1,r,s[x].rs,pos);
    }
    void build(int l,int r,int &x)
    {
    	x=++tot;
    	if(l==r)
    	{
    		s[x].fa=l,s[x].siz=1;
    		return ;
    	}
    	int mid=l+r>>1;
    	build(l,mid,s[x].ls),build(mid+1,r,s[x].rs);
    }
    int find(int x)
    {
    	int fx;
    	while(1)
    	{
    		fx=query(1,n,rt[now],x);
    		if(s[fx].fa!=x)	x=s[fx].fa;
    		else	break;
    	}
    	return fx;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a,b,c,ra,rb;
    	build(1,n,rt[0]);
    	for(i=1;i<=m;i++)
    	{
    		c=rd();
    		if(c==1)
    		{
    			a=rd()^ans,b=rd()^ans;
    			ra=find(a),rb=find(b);
    			if(s[ra].siz>s[rb].siz)	swap(ra,rb);
    			insert(rt[now],rt[now+1],1,n,s[rb].fa,s[rb].siz+s[ra].siz,s[rb].fa),now++;
    			insert(rt[now],rt[now+1],1,n,s[ra].fa,s[ra].siz,s[rb].fa),now++;
    		}
    		if(c==2)
    		{
    			a=rd()^ans;
    			rt[++now]=rt[to[a]];
    		}
    		if(c==3)
    		{
    			a=rd()^ans,b=rd()^ans;
    			ra=find(a),rb=find(b);
    			printf("%d
    ",ans=(s[ra].fa==s[rb].fa));
    		}
    		to[i]=now;
    	}
    	return 0;
    }
  • 相关阅读:
    HDU 5486 Difference of Clustering 图论
    HDU 5481 Desiderium 动态规划
    hdu 5480 Conturbatio 线段树 单点更新,区间查询最小值
    HDU 5478 Can you find it 随机化 数学
    HDU 5477 A Sweet Journey 水题
    HDU 5476 Explore Track of Point 数学平几
    HDU 5475 An easy problem 线段树
    ZOJ 3829 Known Notation 贪心
    ZOJ 3827 Information Entropy 水题
    zoj 3823 Excavator Contest 构造
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6895073.html
Copyright © 2011-2022 走看看