BZOJ 3673 & 3674 可持久化并查集

用可持久化线段树维护并查集的fa数组
要按秩合并
好久不写,有点生疏。
修改时都要开新节点,这样才不会影响之前的版本

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define lp tree[p].l
#define rp tree[p].r

const int N = 2e5 + 7;

struct Node {
    int l, r;
};
int n;

struct Seg {
    Node tree[N * 50];
    int tol;
    void build(int &p, int l, int r) {
        if (!p) p = ++tol;
        if (l == r) {
            tree[p].l = l;
            tree[p].r = 1;
            return;
        }
        build(lp, l, mid);
        build(rp, mid + 1, r);
    }
    void update(int &p, int l, int r, int pos, Node v) {
        tree[++tol] = tree[p];
        p = tol;
        if (l == r) {
            tree[p] = v;
            return;
        }
        if (pos <= mid) update(lp, l, mid, pos, v);
        else update(rp, mid + 1, r, pos, v);
    }
    Node query(int p, int l, int r, int pos) {
        if (l == r) return tree[p];
        if (pos <= mid) return query(lp, l, mid, pos);
        return query(rp, mid + 1, r, pos);
    }
    Node find(int p, int x) {
        Node temp = query(p, 1, n, x);
        if (temp.l == x) return temp;
        return find(p, temp.l);
    }
} seg;

int root[N], m, ans;

int main() {
    scanf("%d%d", &n, &m);
    seg.build(root[0], 1, n);
    for (int opt, l, r, k, i = 1; i <= m; i++) {
        scanf("%d", &opt);
        root[i] = root[i - 1];
        if (opt == 1) {
            scanf("%d%d", &l, &r);
            l ^= ans, r ^= ans;
            Node fx = seg.find(root[i], l), fy = seg.find(root[i], r);
            if (fx.l == fy.l) continue;
            if (fx.r > fy.r) std::swap(fx, fy);
            seg.update(root[i], 1, n, fx.l, {fy.l, fx.r});
            seg.update(root[i], 1, n, fy.l, {fy.l, fx.r + fy.r});
        } else if (opt == 2) {
            scanf("%d", &k);
            k ^= ans;
            root[i] = root[k];
        } else {
            scanf("%d%d", &l, &r);
            l ^= ans, r ^= ans;
            Node fx = seg.find(root[i], l), fy = seg.find(root[i], r);
            ans = fx.l == fy.l;
            printf("%d\n", ans);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Mrzdtz220/p/12310169.html