zoukankan      html  css  js  c++  java
  • 可持久化并查集

    可持久化并查集

    题意

    如题。

    解法

    我们考虑用主席树来维护每一个版本中,x的father,因为我们要做到可持久化, 所以我们不能压缩路径(可能吧) ,我们就需要用到启发式合并。每次将深度较浅的合并到深度较大的集合中,并且,如果两个集合深度相同了的话,将其中的一个深度+1。剩下的就是主席树的基本操作了。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cctype>
    #define INF 2139062143
    #define MAX 0x7ffffffffffffff
    #define del(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    template<typename T>
    inline void read(T&x)
    {
        x=0;T k=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
    }
    const int maxn=1e5+5;
    struct node{
    	int lc,rc,fa,deep;
    }T[maxn*40];
    int root[maxn*2],sz;
    int n,m;
    
    void build(int &x,int l,int r){
    	x=++sz;
    	if(l==r){
    		T[x].fa=l;
    		return;
    	}
    	int mid=(l+r)/2;
    	build(T[x].lc,l,mid);
    	build(T[x].rc,mid+1,r);
    }
    
    void update(int l,int r,int pos,int fa,int &x,int y){
    	T[++sz]=T[y],x=sz;
    	if(l==r) { T[x].fa=fa;return;}
    	int mid=(l+r)/2;
    	if(pos<=mid) update(l,mid,pos,fa,T[x].lc,T[y].lc);
    	else update(mid+1,r,pos,fa,T[x].rc,T[y].rc);
    }
    
    node query(int x,int l,int r,int pos){
    	if(l==r) return T[x];
    	int mid=(l+r)/2;
    	if(pos<=mid) return query(T[x].lc,l,mid,pos);
    	else return query(T[x].rc,mid+1,r,pos);
    }
    
    void add(int x,int l,int r,int pos){
    	if(l==r) { ++T[x].deep;return;}
    	int mid=(l+r)/2;
    	if(pos<=mid) add(T[x].lc,l,mid,pos);
    	else add(T[x].rc,mid+1,r,pos);
    }
    
    node find_fa(int x,int pos){
    	node k=query(x,1,n,pos);
    	if(k.fa==pos) return k;
    	return find_fa(x,k.fa);
    }
    
    void uni(int &x,int y,int pos1,int pos2){
    	x=y;
    	node f1=find_fa(x,pos1),f2=find_fa(x,pos2);
    	if(f1.fa!=f2.fa){
    		if(f1.deep>f2.deep) swap(f1,f2);
    		update(1,n,f1.fa,f2.fa,x,y);
    		if(f1.deep==f2.deep) add(x,1,n,f2.fa);
    	}
    }
    
    int main()
    {
    	read(n),read(m);
    	build(root[0],1,n);
    	for(int i=1;i<=m;i++){
    		int k,x,y;
    		read(k);
    		if(k==1){
    			read(x),read(y);
    			uni(root[i],root[i-1],x,y);
    		}
    		if(k==2){
    			read(x);
    			root[i]=root[x];
    		}
    		if(k==3){
    			read(x),read(y);
    			root[i]=root[i-1];
    			node fa1=find_fa(root[i],x),fa2=find_fa(root[i],y);
    			if(fa1.fa==fa2.fa) printf("1
    ");
    			else printf("0
    ");
    		}
    	}	
    	return 0;
    }
    
  • 相关阅读:
    Eclipse安装Hadoop插件
    (转)Ubuntu14.0.4中hadoop2.4.0伪分布模式配置
    Hadoop--DataNode无法启动
    启动与关闭hadoop
    hadoop中执行命令时发生错误
    strings命令
    Deriving data from ElasticSearch Engine
    elasticsearch data importing
    reading words in your computer and changing to female voice, linux festival text2wave saving wav files
    DDNS client on a Linux machine
  • 原文地址:https://www.cnblogs.com/mrasd/p/9532239.html
Copyright © 2011-2022 走看看