• 【模板】可持久化并查集


    可持久化并查集

    性质

    可持久化并查集 = 可持久化数组 + 并查集 = 主席树 + 并查集
    时间复杂度 (O(n log^2 n))

    (Code)

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int N = 2e5 + 5;
    int n, m, cnt, fa[N * 32], dep[N * 32], rt[N];
    struct node{int ls, rs;}tr[N * 32];
    
    inline void read(int &x)
    {
    	x = 0; int f = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : f), ch = getchar();
    	while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    	x *= f;
    }
    
    void build(int &p, int l, int r)
    {
    	p = ++cnt;
    	if (l == r)
    	{
    		fa[p] = l;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(tr[p].ls, l, mid);
    	build(tr[p].rs, mid + 1, r);
    }
    
    void update(int &u, int v, int l, int r, int x, int y)
    {
    	u = ++cnt, tr[u] = tr[v];
    	if (l == r)
    	{
    		fa[u] = y, dep[u] = dep[v];
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if (x <= mid) update(tr[u].ls, tr[v].ls, l, mid, x, y);
    	else update(tr[u].rs, tr[v].rs, mid + 1, r, x, y);
    }
    
    void Add(int p, int l, int r, int x)
    {
    	if (l == r)
    	{
    		++dep[p];
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if (x <= mid) Add(tr[p].ls, l, mid, x);
    	else Add(tr[p].rs, mid + 1, r, x);
    }
    
    int query(int p, int l, int r, int x)
    {
    	if (l == r) return p;
    	int mid = (l + r) >> 1;
    	if (x <= mid) return query(tr[p].ls, l, mid, x);
    	else return query(tr[p].rs, mid + 1, r, x);
    }
    
    int find(int p, int x)
    {
    	int y = query(p, 1, n, x);
    	if (fa[y] == x) return y;
    	return find(p, fa[y]);
    }
    
    int main()
    {
    	read(n), read(m);
    	build(rt[0], 1, n);
    	for(register int i = 1, op, a, b; i <= m; i++)
    	{
    		read(op);
    		if (op == 1)
    		{
    			rt[i] = rt[i - 1];
    			read(a), read(b);
    			int x = find(rt[i], a), y = find(rt[i], b);
    			if (fa[x] == fa[y]) continue;
    			if (dep[x] > dep[y]) swap(x, y);
    			update(rt[i], rt[i - 1], 1, n, fa[x], fa[y]);
    			Add(rt[i], 1, n, fa[y]);
    		}
    		else if (op == 2) read(a), rt[i] = rt[a];
    		else{
    			read(a), read(b);
    			rt[i] = rt[i - 1];
    			if (fa[find(rt[i], a)] != fa[find(rt[i], b)]) printf("0
    ");
    			else printf("1
    ");
    		}
    	}
    }
    
  • 相关阅读:
    这些天对iframe的初步运用
    后台制作与商品装入
    主页的设计
    DevOps
    Nginx
    DevOps
    DevOps
    Cluster
    Cluster
    Cluster
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/14220215.html
Copyright © 2020-2023  润新知