现在的位置: 首页 > 综合 > 正文

3674: 可持久化并查集加强版 (可持久化线段树)

2017年11月16日 ⁄ 综合 ⁄ 共 1830字 ⁄ 字号 评论关闭
#include<bits/stdc++.h>
using namespace std;


inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x*f;
}


const int maxm = 10000005, maxn = 200005;


struct node {
    int l, r, ls, rs, v, deep;
} tr[maxm];
int n, m, sz, rt[maxn], last;


inline void build(int &k, int l, int r) {
    if (!k)k = ++sz;
    tr[k].l = l;
    tr[k].r = r;
    if (l == r) {
        tr[k].v = l;
        return;
    }
    int mid = (l + r) >> 1;
    build(tr[k].ls, l, mid);
    build(tr[k].rs, mid + 1, r);
}


inline void update(int l, int r, int x, int &y, int pos, int val) {
    y = ++sz;
    if (l == r) {
        tr[y].v = val;
        return;
    }
    tr[y].ls = tr[x].ls;
    tr[y].rs = tr[x].rs;
    int mid = (l + r) >> 1;
    if (pos <= mid)update(l, mid, tr[x].ls, tr[y].ls, pos, val);
    else update(mid + 1, r, tr[x].rs, tr[y].rs, pos, val);
}


inline int query(int k, int l, int r, int x) {
    if (l == r)return k;
    int mid = (l + r) >> 1;
    if (x <= mid)return query(tr[k].ls, l, mid, x);
    else return query(tr[k].rs, mid + 1, r, x);
}


inline void add(int k, int l, int r, int pos) {
    if (l == r) {
        tr[k].deep++;
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid)add(tr[k].ls, l, mid, pos);
    else add(tr[k].rs, mid + 1, r, pos);
}


inline int find(int k, int x) {
    int p = query(k, 1, n, x);
    if (x == tr[p].v)return p;
    return find(k, tr[p].v);
}


int main() {
    n = read();
    m = read();
    build(rt[0], 1, n);
    int f, k, a, b;
    for (int i = 1; i <= m; i++) {
        f = read();
        if (f == 1) {
            rt[i] = rt[i - 1];
            a = read();
            b = read();
            int p = find(rt[i], a), q = find(rt[i], b);
            if (tr[p].v == tr[q].v)continue;
            if (tr[p].deep > tr[q].deep)swap(p, q);
            update(1, n, rt[i - 1], rt[i], tr[p].v, tr[q].v);
            if (tr[p].deep == tr[q].deep)add(rt[i], 1, n, tr[q].v);
        }
        if (f == 2) {
            k = read();
            rt[i] = rt[k];
        }
        if (f == 3) {
            rt[i] = rt[i - 1];
            a = read();
            b = read();
            int p = find(rt[i], a), q = find(rt[i], b);
            if (tr[p].v == tr[q].v)last = 1;
            else last = 0;
            printf("%d\n", last);
        }
    }
    return 0;
}
【上篇】
【下篇】

抱歉!评论已关闭.