【模板】可持久化并查集 未完成

本文探讨了并查集和线段树的数据结构实现,包括路径压缩优化、线段树构建与插入操作,以及如何在不同场景下进行查询与更新。通过案例演示了并查集和线段树在解决动态连通性和区间问题上的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在犹豫是否可以进行路径压缩中......

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;

void setIO(string a){
	string in=a+".in",out=a+".out";
	freopen(in.c_str(),"r",stdin), freopen(out.c_str(),"w",stdout);
}

int read(){
	int a;
	scanf("%d",&a);
	return a;
}

const int maxn=100000+3;

const int const_tree=52;

struct Node{
	int fa, siz;
	Node(int fa=0,int siz=0):fa(fa),siz(siz){}
}node[maxn*const_tree];

int root[maxn*const_tree];

struct Chair_Tree{
	#define lson lson[o]
	#define rson rson[o]

	int cnt_tree;

	void build(int l,int r,int &o){
		if(l>r) return;
		o=++cnt_tree;

		if(l==r){
			node[o]=Node(l,1);
			return;
		}

		int mid=(l+r)>>1;

		build(l,mid,lson[o]);
		build(mid+1,r,rson[o]);
	}

	int insert(int l,int r,int o,int pos,Node k){
		int oo=++cnt_tree;
		lson[oo]=lson[o];
		rson[oo]=rson[o];

		if(l==r){
			node[oo]=k;
			return oo;
		}

		int mid=(l+r)>>1;

		if(pos<=mid) lson[oo]=insert(l,mid,lson,pos,k);
		else rson[oo]=insert(mid+1,r,rson,k);

		return oo;
	}

	Node query(int l,int r,int o,int pos){
		if(l==r) return node[o];

		int mid=(l+r)>>1;

		if(pos<=mid)return query(l,mid,lson,pos);
		else return query(mid+1,r,rson,pos);
	}

}tree;

Node find_fa(int a, int id){
	Node k=tree.query(1,n,root[id],a);
	if(k.fa==a) return k;
	else return find_fa(k.fa, id);
}

int n,m;

void work(){
	n=read(),m=read();

	tree.build(1,n,root[0]);

    for(int i=1;i<=m;++i){
    	int opt,a,b,k;
    	scanf("%d",&opt);

    	switch(opt){

    		case 1:{
    			a=read(),b=read();
    			Node x=find_fa(a,root[i-1]);             //node of a's ancester
    			Node y=find_fa(b,root[i-1]);             //node of b's ancester

    			Node A=tree.query(1,n,root[i-1],a);      //node a
    			Node B=tree.query(1,n,root[i-1],b);      //node b
    			if(x==y) continue;

    			//merge b to a
    			
    			if(x.siz > y.siz){
    				int rt=tree.insert(1,n,root[i-1],b,Node(x.fa,B.siz));
    				root[i]=tree.insert(1,n,rt,a,Node())
    			}
    			else{

    			}
    			break;
    		}

    		case 2:{
    			k=read();
    			root[i]=root[k];
    			break;
    		}

    		case 3:{
    			a=read(),b=read();
    			break;
    		}
    	}
    }
}
int main(){
	setIO("input");
	work();
	return 0;
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值