lct

#include <cstdio>
#include <algorithm>
#define Get(x) (t[t[x].f].c[1] == x)
#define Nroot(x) (t[t[x].f].c[Get(x)] == x)
#define ls(x) t[x].c[0]
#define rs(x) t[x].c[1]

const int N = 1e5 + 5;

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

struct Tree {
    int x, s, f, c[2];
    bool tag;
}t[N];

int n, m;

void Pushup(int x) {
    t[x].s = t[x].x ^ t[ls(x)].s ^ t[rs(x)].s;
}

void Rotate(int x) {
    int y = t[x].f, z = t[y].f, s = Get(x);
    if (Nroot(y)) t[z].c[Get(y)] = x; t[x].f = z;
    t[y].c[s] = t[x].c[s^1]; t[t[x].c[s^1]].f = y;
    t[x].c[s^1] = y; t[y].f = x;
    Pushup(y); Pushup(x);
}

void Pushdown(int x) {
    if (!t[x].tag) return;
    t[x].tag = 0;
    std::swap(ls(x), rs(x));
    t[ls(x)].tag ^= 1, t[rs(x)].tag ^= 1;
}

void Update(int x) {
    if (Nroot(x)) Update(t[x].f); Pushdown(x);
}

void Splay(int x) {
    Update(x);
    while (Nroot(x)) {
        int y = t[x].f, z = t[y].f;
        if (Nroot(y)) Get(x) == Get(y) ? Rotate(y) : Rotate(x);
        Rotate(x);
    }
}

void Access(int x) {
    for (int y = 0; x; y = x, x = t[x].f)
        Splay(x), t[x].c[1] = y, Pushup(x);
}

void Mroot(int x) {
    Access(x); Splay(x); t[x].tag ^= 1;
}

int Froot(int x) {
    Access(x); Splay(x);
    while (t[x].c[0]) x = t[x].c[0];
    return x;
}

void Split(int x, int y) {
    Mroot(x); Access(y); Splay(y);
}

void Link(int x, int y) {
    if (Froot(x) != Froot(y)) 
        Mroot(x), t[x].f = y;
}

void Cut(int x, int y) {
    if (Froot(x) != Froot(y)) return;
    Split(x, y);
    if (t[y].c[0] == x && !t[x].c[1]) t[x].f = t[y].c[0] = 0, Pushup(y);
}

int main() {
    n = read(); m = read();
    for (int i = 1; i <= n; ++i)
        t[i].x = read();
    while (m--) {
        int od = read(), x = read(), y = read();
        if (od == 0) Split(x, y), printf("%d
", t[y].s);
        else if (od == 1) Link(x, y);
        else if (od == 2) Cut(x, y);
        else if (od == 3) Access(x), Splay(x), t[x].x = y, Pushup(x);
    }
    return 0;
}

推荐 FlashHu的lct博客

原文地址:https://www.cnblogs.com/shawk/p/14160444.html