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");
    		}
    	}
    }
    
  • 相关阅读:
    t讯src的一点小秘密
    SQL注入科普
    U盘,移动硬盘显示显示需要格式化怎么修复
    Linux提高工作效率的命令
    SpringBoot配置文件加载位置与优先级
    如何选择分布式事务形态(TCC,SAGA,2PC,基于消息最终一致性等等)
    Java IO总结
    Java并发编程指南
    Linux下的crontab定时执行任务命令详解
    Zookeeper的功能以及工作原理
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366344.html
Copyright © 2011-2022 走看看