树堆(Treap)

无旋式 Treap

#include <cstdio>
#include <cstdlib>
#include <algorithm>

const int MAXN = 100005;

struct Treap {
    struct Node {
        Node *lc, *rc;
        int val, size;
        bool rev;

        Node() {}
        Node(int val, Node *lc = NULL, Node *rc = NULL) : val(val), lc(lc), rc(rc), rev(false) {
            maintain();
        }

        void reverse() {
            std::swap(lc, rc);
            rev ^= 1;
        }

        void pushDown() {
            if (rev) {
                if (lc) lc->reverse();
                if (rc) rc->reverse();
                rev = false;
            }
        }

        void maintain() {
            size = (lc ? lc->size : 0) + 1 + (rc ? rc->size : 0);
        }

        void print() {
            pushDown();
            if (lc) lc->print();
            printf("%d ", val);
            if (rc) rc->print();
        }
    } *root, _pool[MAXN], *_curr;

    Treap() : root(NULL), _curr(_pool) {}

    static int size(const Node *u) { return u ? u->size : 0; }

    Node *_build(int l, int r) {
        if (l > r) return NULL;
        int mid = l + ((r - l) >> 1);
        return new (_curr++) Node(mid, _build(l, mid - 1), _build(mid + 1, r));
    }
    void build(int l, int r) {
        root = _build(l, r);
    }

    Node *merge(Node *a, Node *b) {
        if (!a) return b;
        if (!b) return a;

        if (rand() % (a->size + b->size) < a->size) {
            a->pushDown();
            a->rc = merge(a->rc, b);
            a->maintain();
            return a;
        } else {
            b->pushDown();
            b->lc = merge(a, b->lc);
            b->maintain();
            return b;
        }
    }

    std::pair<Node *, Node *> split(Node *u, int pos) {
        std::pair<Node *, Node *> res(NULL, NULL);
        if (!u) return res;
        u->pushDown();
        if (pos <= size(u->lc)) {
            res = split(u->lc, pos);
            u->lc = res.second;
            u->maintain();
            res.second = u;
        } else {
            res = split(u->rc, pos - size(u->lc) - 1);
            u->rc = res.first;
            u->maintain();
            res.first = u;
        }
        return res;
    }

    void reverse(int l, int r) {
        std::pair<Node *, Node *> L = split(root, l - 1);
        std::pair<Node *, Node *> R = split(L.second, r - l + 1);
        R.first->reverse();
        root = merge(merge(L.first, R.first), R.second);
    }

    void print() {
        root->print();
        puts("");
    }
} treap;

int main() {
    int n, m;
    scanf("%d %d", &n, &m);

    treap.build(1, n);

    for (int i = 0, l, r; i < m; i++) {
        scanf("%d %d", &l, &r);
        treap.reverse(l, r);
    }

    treap.print();

    return 0;
}

results matching ""

    No results matching ""