• 浅谈可持续化并查集


    窝太菜了只配浅谈呃呃呃

    前置芝士

    主席树& 并查集

    主席树模板题

    可持久化并查集 , 差不多可能大概应该就是在主席树上做并查集 , 用主席树维护每个点的父亲...

    修改

    每次新建一个节点

    值得一提的是 , 如果用路径压缩会TM双LE2333 , 这里只能按秩合并 即每次把深度小的并查集合并到深度高的并查集中去(如果两个深度相同 , 则其中一个并查集深度++ ) 可以画图感性理解一下

    查询

    查询该点在当前版本中的位置

    感觉讲的好苍白呃呃呃 , 还是直接看我的代码(垃圾堆)自行理解吧呃呃呃

    #include <bits/stdc++.h>
    using namespace std;
    #define mid (l + r) / 2
    const int N = 200005;
    
    int n, m, cnt;
    int deep[N * 30], f[N * 30]; // deep记录的是每个点的深度 , f记录的是父亲
    int T[N * 30], L[N * 30], R[N * 30]; //这里试了几次....开N << 5就炸了(为什么是TLE) 30倍应该刚刚好
    
    int build(int l, int r) {
    	int rt = ++cnt;
    
    	if(l == r) {
    		f[rt] = l;
    		return rt;
    	}
    	L[rt] = build(l, mid);
    	R[rt] = build(mid + 1, r);
    	return rt;
    }
    int updata(int pre, int l, int r, int ppx, int k) { // pre为上一个版本的当前节点(感性理解233) , ppx为待修改的位置, k为修改的值
    	int rt = ++cnt;
    	
    	L[rt] = L[pre]; R[rt] = R[pre];
    	if(l == r) {
    		f[rt] = k; 
    		deep[rt] = deep[pre]; // 别忘了继承这个深度
    		return rt;
    	}
    	if(ppx <= mid) L[rt] = updata(L[pre], l, mid, ppx, k);
    	else R[rt] = updata(R[pre], mid + 1, r, ppx, k);
    	return rt;
    }
    int query(int u, int l, int r, int ppx) { // u为当前节点编号
    	if(l == r) return u;
    	if(ppx <= mid) return query(L[u], l, mid, ppx);
    	else return query(R[u], mid + 1, r, ppx);
    }
    void add(int u, int l, int r, int ppx) {//增加当前并查集的深度
    	if(l == r) {
    		deep[u]++;
    		return ;
    	}
    	if(l < r) {
    		if(ppx <= mid) add(L[u], l, mid, ppx);
    		else add(R[u], mid + 1, r, ppx);
    	}
    }
    int find(int u, int x) {
    	int fx = query(u, 1, n, x);
    	if(x == f[fx]) return fx;
    	return find(u, f[fx]);
    }
    int main() {
    	ios :: sync_with_stdio(0);
    
    	cin >> n >> m;
    	T[0] = build(1, n);
    	for(int i = 1; i <= m; i++) {
    		int opt, a, b;
    		cin >> opt;
    		if(opt == 1) { 
    			cin >> a >> b;
    			T[i] = T[i - 1];
    			int fa = find(T[i], a);
    			int fb = find(T[i], b);
    			if(f[fa] == f[fb]) continue;
    			if(deep[fa] > deep[fb]) swap(fa, fb);
    			T[i] = updata(T[i - 1], 1, n, f[fa], f[fb]);
    			if(deep[fa] == deep[fb]) add(T[i], 1, n, f[fb]);
    		}
    		else if(opt == 2) {
    			cin >> a;
    			T[i] = T[a];
    		}
    		else {
    			cin >> a >> b;
    			T[i] = T[i - 1];
    			if(f[find(T[i], a)] == f[find(T[i], b)]) cout << 1 << endl;
    			else cout << 0 << endl;
    		}
    	}return 0;
    }
    

    有什么问题可以直接在评论区告诉窝的鹅鹅鹅

    不会吧不会吧不会真有人看的叭

  • 相关阅读:
    FastDFS搭建
    关于nginx性能优化CPU参数worker_cpu_affinity使用说明
    LNMP一键安装升级nginx及php常用设置 SFTP管理指南
    Nginx的防盗链
    Nginx+PHP 配置漏洞:静态文件都可以当作 PHP 解析
    Nginx技巧:灵活的server_name
    数据库分表时OR Mapping方法
    nginx配置多域名反向代理
    nginx server 实时监控
    转:SQL Server 2005数据库分表实例
  • 原文地址:https://www.cnblogs.com/hyxss/p/13569342.html
Copyright © 2020-2023  润新知