zoukankan      html  css  js  c++  java
  • BZOJ3674 可持久化并查集加强版

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

     本文作者:ljh2000 

    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    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
     

    正解:启发式合并+线段树

    解题报告:

      这道题是启发式合并的练手好题…

      为了满足题目要求,我需要对于每个历史版本维护fa,想想就会发现这个其实和主席树是有相通之处的,都是每个节点维护了一棵线段树,然后每次修改只会修改到一条链,这道题也是一样的。

      那么我对于每个节点维护一棵线段树,其中只有叶子节点里面存储了关键信息,其余节点其实没有任何信息的存储。

      我记录一下每个历史版本的线段树的根节点,可以把当前状态直接指向历史版本中的根,所以可以做到O(1)撤销。

      查询的话直接查在当前状态下是否是同一个祖先即可,注意不能路径压缩。还有就是讲一下按秩合并的相关问题,首先秩表示的是以这个元素为祖先的所有元素中的最大深度。

      很明显,并查集的复杂度直接和查询的最大深度有关,所以我应该以最大深度作为合并时的评判标准。

      然后只有在合并之前两棵子树秩相同的时候,才需要修改新树的秩,否则由于小的那个的秩<大的那个的秩,最大深度不会超过大的那个。

      这是一点细节上的说明。

    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    using namespace std;
    typedef long long LL;
    const int MAXN = 200011;
    const int MAXM = 5000011;
    int n,m,root[MAXN],cnt,ans;
    struct node{ int ls,rs,deep,fa; }a[MAXM];
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void build(int &k,int l,int r){
    	k=++cnt; if(l==r) { a[k].deep=1; a[k].fa=l; return ; }
    	int mid=(l+r)>>1; build(a[k].ls,l,mid); build(a[k].rs,mid+1,r);
    }
    
    inline int query(int rt,int l,int r,int val){
    	int u=rt,mid;
    	while(1) {
    		if(l==r) return u; mid=(l+r)>>1;
    		if(val<=mid) r=mid,u=a[u].ls;
    		else l=mid+1,u=a[u].rs;
    	}
    }
    
    inline void add(int &k,int from,int l,int r,int val){
    	k=++cnt; if(l==r) { a[k].fa=val; a[k].deep=a[from].deep+1;/*!!!*/ return ; }
    	a[k].ls=a[from].ls; a[k].rs=a[from].rs;
    	int mid=(l+r)>>1;
    	if(val<=mid) add(a[k].ls,a[from].ls,l,mid,val);
    	else add(a[k].rs,a[from].rs,mid+1,r,val);
    }
    
    
    inline void update(int &k,int from,int l,int r,int A,int Fa){
    	k=++cnt; if(l==r) { a[k].fa=Fa; a[k].deep=a[from].deep;/*!!!*/ return ; }
    	a[k].ls=a[from].ls; a[k].rs=a[from].rs;
    	int mid=(l+r)>>1;
    	if(A<=mid) update(a[k].ls,a[from].ls,l,mid,A,Fa);
    	else update(a[k].rs,a[from].rs,mid+1,r,A,Fa);
    }
    
    inline int find(int rt,int x){//在rt为根的线段树中查找x所在的集合的祖先
    	int Node=query(rt,1,n,x);//先在线段树中找到x所在的叶子节点对应的线段树节点编号
    	if(a[Node].fa==x) return Node;
    	return find(rt,a[Node].fa);
    }
    
    inline void work(){
    	n=getint(); m=getint(); ans=0; 
    	build(root[0],1,n); int x,y,r1,r2,ljh; 
    	for(int i=1;i<=m;i++) {
    		ljh=getint(); root[i]=root[i-1];
    		if(ljh==1) {
    			x=getint(); y=getint();	x^=ans; y^=ans;
    			r1=find(root[i],x); r2=find(root[i],y);	if(a[r1].fa==a[r2].fa) continue;//!!!
    			if(a[r1].deep>a[r2].deep) swap(r1,r2);
    			update(root[i],root[i-1],1,n,a[r1].fa,a[r2].fa);
    			if(a[r1].deep==a[r2].deep) add(root[i],root[i],1,n,a[r2].fa);//考虑最大深度相等时,合并之后秩会+1
    		}
    		else if(ljh==2) { x=getint(); x^=ans; root[i]=root[x]; }
    		else {
    			x=getint(); y=getint(); x^=ans; y^=ans;
    			r1=find(root[i],x); r2=find(root[i],y);
    			if(r1==r2) { puts("1"); ans=1; } else { puts("0"); ans=0; }
    		}
    	}
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

  • 相关阅读:
    3星|《财经》2017年第27期:比亚迪正在计划将其电池产能放开给市场
    4星+|《赋能:打造应对不确定性的敏捷团队》:海豹突击队学习伊拉克“基地”组织的组织形式并且最终战胜对方的故事
    2星|《腾讯产品法》:标题党,作者只有QQ手机助手的短期产品经验
    1星|《进阶》:文风模仿古龙,内容是居委会大妈级别
    4星|《好战略,坏战略》:理论不错,案例偏旧有事后诸葛亮的嫌疑,没敢预测未来
    2星|《下一个倒下的会不会是华为(终极版)》:小报软文风格,篇幅较长但有效信息太少,缺乏全面宏观的视角和数据
    4星|《心流:最优体验心理学》:如何在工作生活中发现幸福:找到意义与目标并且专注其中
    3星|《经济学泰斗的管理思路》:对金融专家来说,一份赏心悦目的报告在效果上相当于企业年收入增加20%。
    String.IndexOf String.IndexOf String.Substring
    Debug 和 Release 编译方式的本质区别
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6291348.html
Copyright © 2011-2022 走看看