Link-Cut Tree

#include <cstdio>
#include <algorithm>

const int MAXN = 30005;

struct LinkCutTree {
    struct Node {
        Node *c[2], *fa, *pathFa;
        int val, max;
        bool rev;

        Node() {}
        Node(int val) : val(val), max(val), rev(false), fa(NULL), pathFa(NULL), c() {}

        int relation() { return fa->c[1] == this; }

        void maintain() {
            max = val;
            if (c[0]) max = std::max(max, c[0]->max);
            if (c[1]) max = std::max(max, c[1]->max);
        }

        void pushDown() {
            if (rev) {
                std::swap(c[0], c[1]);
                if (c[0]) c[0]->rev ^= 1;
                if (c[1]) c[1]->rev ^= 1;
                rev = false;
            }
        }

        void rotate() {
            std::swap(pathFa, fa->pathFa);

            Node *o = fa;
            int x = relation();

            fa = o->fa;
            if (fa) fa->c[o->relation()] = this;

            o->c[x] = c[x ^ 1];
            if (c[x ^ 1]) c[x ^ 1]->fa = o;

            c[x ^ 1] = o;
            o->fa = this;

            o->maintain();
            maintain();
        }

        void splay() {
            while (fa) {
                if (fa->fa) fa->fa->pushDown();
                fa->pushDown();
                pushDown();

                if (!fa->fa) rotate();
                else if (fa->relation() == relation()) fa->rotate(), rotate();
                else rotate(), rotate();
            }
        }

        void evert() {
            access();
            splay();
            rev ^= 1;
        }

        void expose() {
            splay();
            pushDown();
            if (c[1]) {
                std::swap(c[1]->fa, c[1]->pathFa);
                c[1] = NULL;
                maintain();
            }
        }

        bool splice() {
            splay();
            if (!pathFa) return false;

            pathFa->expose();
            pathFa->c[1] = this;
            std::swap(fa, pathFa);
            fa->maintain();
            return true;
        }

        void access() {
            expose();
            while (splice());
        }

        int query() {
            access();
            splay();
            return max;
        }
    } *N[MAXN], _pool[MAXN], *_curr;

    LinkCutTree() : _curr(_pool) {}

    void makeTree(int u, int val) {
        N[u] = new (_curr++) Node(val);
    }

    void link(int u, int v) {
        N[v]->evert();
        N[v]->pathFa = N[u];
    }

    void cut(int u, int v) {
        N[u]->evert();
        N[v]->access();
        N[v]->splay();
        N[v]->pushDown();
        N[v]->c[0]->fa = NULL;
        N[v]->c[0] = NULL;
        N[v]->maintain();
    }

    int query(int u, int v) {
        N[u]->evert();
        return N[v]->query();
    }
} lct;

int main() {

    return 0;
}

results matching ""

    No results matching ""