bzoj 3282 Tree LCT

题面

题目传送门

解法

LCT模板题

代码

#include <bits/stdc++.h>
#define N 300010
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
    x = 0; int f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); x *= f;
}
namespace LCT {
    struct Node {
        int fa, rev, val, sum, pathfa, child[2];
    } t[N];
    int son(int x, int y) {return t[x].child[1] == y;}
    int sum(int x) {return t[x].sum;}
    void rev(int x) {t[x].rev ^= 1;}
    void pushdown(int x) {
        if (!x) return;
        int k = t[x].rev;
        if (k) {
            swap(t[x].child[0], t[x].child[1]), rev(x);
            rev(t[x].child[0]), rev(t[x].child[1]);
        }
    }
    void update(int x) {if (!x) return; t[x].sum = t[x].val ^ sum(t[x].child[0]) ^ sum(t[x].child[1]);}
    void Connect(int x, int y, int k) {
        if (x) t[x].child[k] = y;
        if (y) t[y].fa = x; update(x);
    }
    void Rotate(int x) {
        int y = t[x].fa, z = t[y].fa;
        pushdown(y), pushdown(x);
        swap(t[x].pathfa, t[y].pathfa);
        int a = son(y, x), b = !a;
        Connect(z, x, son(z, y));
        Connect(y, t[x].child[b], a);
        Connect(x, y, b);
        update(y), update(x);
    }
    void Splay(int x) {
        while (t[x].fa) {
            int y = t[x].fa, z = t[y].fa;
            if (z) {
                pushdown(z), pushdown(y);
                (son(z, y) ^ son(y, x)) ? Rotate(x) : Rotate(y);
            }
            Rotate(x);
        }
    }
    void expose(int x) {
        Splay(x), pushdown(x);
        int y = t[x].child[1];
        t[y].fa = 0, t[y].pathfa = x;
        t[x].child[1] = 0, update(x);
    }
    void access(int x) {
        for (expose(x); t[x].pathfa; Splay(x)) {
            expose(t[x].pathfa);
            Connect(t[x].pathfa, x, 1);
            t[x].pathfa = 0;
        }
    }
    void evert(int x) {access(x), Splay(x), rev(x);}
    int findroot(int x) {
        access(x), Splay(x);
        for (pushdown(x); t[x].child[0]; x = t[x].child[0], pushdown(x));
        Splay(x); return x;
    }
    void link(int x, int y) {
        if (findroot(x) == findroot(y)) return;
        evert(y), t[y].pathfa = x;
    }
    void cut(int x, int y) {
        evert(x), access(y);
        Splay(y), pushdown(y);
        t[t[y].child[0]].fa = 0;
        t[y].child[0] = 0, pushdown(y);
    }
    void modify(int x, int v) {Splay(x), t[x].val = v, update(x);}
    int query(int x, int y) {
        evert(x), access(y), Splay(y);
        return t[y].sum;
    }
}
int main() {
    using namespace LCT;
    int n, m; read(n), read(m);
    for (int i = 1; i <= n; i++) {
        int x; read(x);
        t[i].val = x;
    }
    map <pair <int, int>, int> h;
    for (int i = 1; i <= m; i++) {
        int op, x, y;
        read(op), read(x), read(y);
        if (op == 0) cout << query(x, y) << "\n";
        if (op == 1) link(x, y), h[make_pair(x, y)] = 1;
        if (op == 2)
            if (h[make_pair(x, y)]) cut(x, y), h[make_pair(x, y)] = 0;
        if (op == 3) modify(x, y);
    }
    return 0;
}

posted @ 2018-08-14 22:10  谜のNOIP  阅读(70)  评论(0编辑  收藏  举报