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

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ3673


    题意概括

    n个集合 m个操作
    操作:
    1 a b 合并a,b所在集合
    2 k 回到第k次操作之后的状态(查询算作操作)
    3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

    0<n,m<=2*10^4


    题解

      上板子


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=20005;
    bool isd(char ch){
    	return '0'<=ch&&ch<='9';
    }
    void read(int &x){
    	x=0;
    	char ch=getchar();
    	while (!isd(ch))
    		ch=getchar();
    	while (isd(ch))
    		x=x*10+ch-48,ch=getchar();
    }
    int n,m,size,root[N],fa[N*50],ls[N*50],rs[N*50],depth[N*50];
    int build(int L,int R){
    	int rt=++size;
    	if (L==R){
    		fa[rt]=L,depth[rt]=0;
    		return rt;
    	}
    	int mid=(L+R)>>1;
    	ls[rt]=build(L,mid);
    	rs[rt]=build(mid+1,R);
    	return rt;
    }
    int query(int rt,int le,int ri,int pos){
    	if (le==ri)
    		return rt;
    	int mid=(le+ri)>>1;
    	if (pos<=mid)
    		return query(ls[rt],le,mid,pos);
    	else
    		return query(rs[rt],mid+1,ri,pos);
    }
    void Modify(int prt,int &rt,int le,int ri,int pos,int val){
    	rt=++size;
    	if (le==ri){
    		fa[rt]=val;
    		depth[rt]=depth[prt];
    		return;
    	}
    	ls[rt]=ls[prt],rs[rt]=rs[prt];
    	int mid=(le+ri)>>1;
    	if (pos<=mid)
    		Modify(ls[prt],ls[rt],le,mid,pos,val);
    	else
    		Modify(rs[prt],rs[rt],mid+1,ri,pos,val);
    }
    void add(int rt,int le,int ri,int pos){
    	if (le==ri){
    		depth[rt]++;
    		return;
    	}
    	int mid=(le+ri)>>1;
    	if (pos<=mid)
    		add(ls[rt],le,mid,pos);
    	else
    		add(rs[rt],mid+1,ri,pos);
    }
    int find(int rt,int pos){
    	int p=query(rt,1,n,pos);
    	if (pos==fa[p])
    		return p;
    	return find(rt,fa[p]);
    }
    int main(){
    	size=0;
    	read(n),read(m);
    	root[0]=build(1,n);
    	for (int i=1;i<=m;i++){
    		int op,a,b;
    		root[i]=root[i-1];
    		read(op),read(a);
    		if (op==1){
    			read(b);
    			a=find(root[i],a),b=find(root[i],b);
    			if (fa[a]==fa[b])
    				continue;
    			if (depth[a]>depth[b])
    				swap(a,b);
    			Modify(root[i-1],root[i],1,n,fa[a],fa[b]);
    			if (depth[a]==depth[b])
    				add(root[i],1,n,fa[b]);
    		}
    		else if (op==2)
    			root[i]=root[a];
    		else {
    			root[i]=root[i-1];
    			read(b);
    			a=find(root[i],a),b=find(root[i],b);
    			printf("%d
    ",fa[a]==fa[b]);
    		}
    	}
    	return 0;
    } 
    

      

  • 相关阅读:
    MySQL数据库命令行界面不支持中文
    mysqldump使用方法(MySQL数据库的备份与恢复)
    MySQL性能测试初试(1)--sysbench
    composer安装
    Java关键字[static].md
    Docker容器
    Docker概述及安装
    Docker镜像
    定时任务[crontab]
    Linux下的curl工具
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3673.html
Copyright © 2011-2022 走看看