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


    【模板】可持久化并查集

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define y1 y11
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define pdd pair<double, double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //head
    
    struct Sustainable_DSU {
        static const int N = 2e5 + 5, M = 4e6 + 5;
        int root[N], lson[M], rson[M], fa[M], rnk[M], tot, n;
    
        inline void build(int &rt, int l, int r) {
            rt = ++tot;
            if(l == r) {fa[rt] = l; return ;}
            int m = l+r >> 1;
            build(lson[rt], l, m);
            build(rson[rt], m+1, r);
        }
        inline void init(int _n) {
            n = _n;
            tot = 0;
            build(root[0], 1, n);
        }
        inline void Update(int old, int &rt, int p, int v, int l, int r) {
            rt = ++tot;
            lson[rt] = lson[old], rson[rt] = rson[old];
            if(l == r) {
                fa[rt] = v;
                rnk[rt] = rnk[old];
                return ;
            }
            int m = l+r >> 1;
            if(p <= m) Update(lson[rt], lson[rt], p, v, l, m);
            else Update(rson[rt], rson[rt], p, v, m+1, r);
        }
        inline void update(int rt, int p, int l, int r) {
            if(l == r) { rnk[rt]++; return ;}
            int m = l+r >> 1;
            if(p <= m) update(lson[rt], p, l, m);
            else update(rson[rt], p, m+1, r);
        }
        ///返回rt版本p位置fa数组下标
        inline int query(int rt, int p, int l, int r) {
            if(l == r) return rt;
            int m = l+r >> 1;
            if(p <= m) return query(lson[rt], p, l, m);
            else return query(rson[rt], p, m+1, r);
        }
        ///返回rt版本p所在并查集fa数组下标
        inline int Find(int rt, int p) {
            int now = query(rt, p, 1, n);
            if(fa[now] == p) return now;
            else return Find(rt, fa[now]);
        }
        ///在i时刻合并x和y所在并查集
        inline void Merge(int i, int x, int y) {
            root[i] = root[i-1];
            int px = Find(root[i], x), py = Find(root[i], y);
            if(fa[px] != fa[py]) {
                if(rnk[px] > rnk[py]) swap(px, py);
                Update(root[i-1], root[i], fa[px], fa[py], 1, n);
                if(rnk[px] == rnk[py]) update(root[i], fa[py], 1, n);
            }
        }
    }s;
    int n, m, op, a, b;
    int main() {
        scanf("%d %d", &n, &m);
        s.init(n);
        for (int i = 1; i <= m; ++i) {
            scanf("%d", &op);
            if(op == 1) scanf("%d %d", &a, &b), s.Merge(i, a, b);
            else if(op == 2) scanf("%d", &a), s.root[i] = s.root[a];
            else {
                scanf("%d %d", &a, &b);
                s.root[i] = s.root[i-1];
                a = s.Find(s.root[i], a);
                b = s.Find(s.root[i], b);
                if(s.fa[a] == s.fa[b]) printf("1
    ");
                else printf("0
    ");
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    canvas 画一个钟表
    .net防止写文件线程冲突
    .net中params以前没关注过的一个现象
    dom属性和特性
    数组常用方法
    新手配置vux
    改变placeholder的字体颜色大小
    设置cookie,删除cookie,读取cookie
    css 画三角形
    audio元素和video元素在ios和andriod中无法自动播放
  • 原文地址:https://www.cnblogs.com/Accpted/p/11375358.html
Copyright © 2020-2023  润新知