zoukankan      html  css  js  c++  java
  • 【BZOJ3674】—可持久化并查集加强版(可持久化并查集)

    传送门

    我还以为可持久化并查集是什么呢

    可持久化并查集==可持久化++并查集==主席树++并查集

    考虑到每次状态只会修改一个集合

    于是就想可持久化数组一样

    维护一颗主席树来维护每个点的fafa

    #include<bits/stdc++.h>
    using namespace std;
    #define gc getchar
    #define ll long long
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=gc();}
    	while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48),ch=gc();}
    	return res*f;
    }
    #undef gc
    const int N=200005;
    const int Log=30;
    int lc[N*Log],rc[N*Log],fa[N*Log],dep[N*Log],n,m,tot,rt[N*Log];
    #define mid ((l+r)>>1)
    void buildtree(int &u,int l,int r){
    	u=++tot;
    	if(l==r){fa[u]=l;return;}
    	buildtree(lc[u],l,mid),buildtree(rc[u],mid+1,r);
    }
    void merge(int pre,int &u,int l,int r,int pos,int f){
    	u=++tot,lc[u]=lc[pre],rc[u]=rc[pre];
    	if(l==r){
    		fa[u]=f,dep[u]=dep[pre];return;
    	}
    	if(pos<=mid)merge(lc[pre],lc[u],l,mid,pos,f);
    	else merge(rc[pre],rc[u],mid+1,r,pos,f);
    }
    void update(int u,int l,int r,int pos){
    	if(l==r){dep[u]++;return;}
    	if(pos<=mid)update(lc[u],l,mid,pos);
    	else update(rc[u],mid+1,r,pos);
    }
    int query(int u,int l,int r,int pos){
    	if(l==r)return u;
    	if(pos<=mid)return query(lc[u],l,mid,pos);
    	else return query(rc[u],mid+1,r,pos);
    }
    int find(int u,int pos){
    	int now=query(u,1,n,pos);
    	if(fa[now]==pos)return now;
    	return find(u,fa[now]);
    }
    int main(){
    	n=read(),m=read();
    	buildtree(rt[0],1,n);
    	for(int i=1;i<=m;i++){
    		int op=read(),x=read();
    		if(op==1){
    			rt[i]=rt[i-1];
    			int y=read();
    			int f1=find(rt[i],x),f2=find(rt[i],y);
    			if(fa[f1]!=fa[f2]){
    				if(dep[f1]>dep[f2])swap(f1,f2);
    				merge(rt[i-1],rt[i],1,n,fa[f1],fa[f2]);
    				if(dep[f1]==dep[f2])update(rt[i],1,n,fa[f2]);
    			}
    		}
    		else if(op==2)rt[i]=rt[x];
    		else if(op==3){
    			int y=read();
    			rt[i]=rt[i-1];
    			int f1=find(rt[i],x),f2=find(rt[i],y);
    			if(fa[f1]==fa[f2])puts("1");
    			else puts("0");
    		}
    	}
    }
    
  • 相关阅读:
    MySQl数据约束练习
    MySQL查询实例
    网络通信协议简介(TCP与UDP)
    数据类型转换
    C++编译过的C代码为什么要用extern C
    hashtable
    以RB-tree为底层机制的几个关联式容器
    红黑树(RB-Tree)
    slist
    deque
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366344.html
Copyright © 2011-2022 走看看