fhq treap 玄关求调
查看原帖
fhq treap 玄关求调
636977
CC__DIAMOND楼主2024/6/20 19:38

rt,过不去样例,总会有几个节点的 size 莫名其妙变成0

#include <bits/stdc++.h>
#include <cassert>

#define BAR cout << "*******\n";
#define fst first
#define snd second
#define INFILE(x) freopen(x, "r", stdin)
#define OUTFILE(x) freopen(x, "w", stdout)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
using namespace std;
using ll = long long;
using ul = unsigned long long;
using ui = unsigned int;
using db = double;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pll = pair<ll, ll>;

static mt19937 rng;

template <typename T, int N> struct treap {
    struct node {
        int l, r, size;
        T val;
        unsigned rnd;

        void init(T v) {
            val = v;
            l = r = 0;
            size = 1;
            rnd = rng();
        }
    } nodes[N];

    int root = 0, tot = 0;

    void push_up(int node) {
        nodes[node].size =
            nodes[nodes[node].l].size + nodes[nodes[node].r].size;
    }

    void split(int node, T v, int &x, int &y) {
        if (!node) {
            x = y = 0;
            return;
        }
        if (v < nodes[node].val) {
            y = node;
            split(nodes[node].l, v, x, nodes[node].l);
        } else {
            x = node;
            split(nodes[node].r, v, nodes[node].r, y);
        }
        push_up(node);
        assert(nodes[node].size || !node);
    }

    int merge(int x, int y) {
        if (!x) return y;
        if (!y) return x;
        if (nodes[x].rnd > nodes[y].rnd) {
            nodes[x].r = merge(nodes[x].r, y);
            push_up(x);
            assert(nodes[x].size);
            return x;
        } else {
            nodes[y].l = merge(x, nodes[y].l);
            push_up(y);
            assert(nodes[y].size);
            return y;
        }
        
    }

    void insert(T v) {
        nodes[++tot].init(v);
        if (!root) {
            root = tot;
            return;
        }
        int x, y;
        split(root, v, x, y);
        int z = tot;
        root = merge(merge(x, z), y);
    }

    void del(T v) {
        int x, y, z;
        split(root, v, x, z);
        split(x, v - 1, x, y);
        y = merge(nodes[y].l, nodes[y].r);
        root = merge(merge(x, y), z);
    }

    int rank(T v) {
        int x, y;
        split(root, v - 1, x, y);
        int res = nodes[x].size + 1;
        root = merge(x, y);
        return res;
    }

    T get_nth(int node, int n) {
        int lsz = nodes[nodes[node].l].size + 1;
        if (lsz == n) {
            return nodes[node].val;
        } else if (n < lsz) {
            return get_nth(nodes[node].l, n);
        } else {
            return get_nth(nodes[node].r, n - lsz);
        }
    }

    T nth(int n) { return get_nth(root, n); }

    T prec(T v) {
        int x, y;
        split(root, v - 1, x, y);
        T res = get_nth(x, nodes[x].size);
        root = merge(x, y);
        return res;
    }

    T succ(T v) {
        int x, y;
        split(root, v, x, y);
        T res = get_nth(y, 1);
        root = merge(x, y);
        return res;
    }
};

constexpr int max_n = 1e5 + 10;
treap<int, max_n> tree;

int main() {
    // INFILE("IOFile/P3369_6.in");
    ios::sync_with_stdio(0);
    cin.tie(0);
    int op, k, T;
    cin >> T;
    while (T--) {
        cin >> op >> k;
        switch (op) {
        case 1:
            tree.insert(k);
            break;
        case 2:
            tree.del(k);
            break;
        case 3:
            cout << tree.rank(k) << '\n';
            break;
        case 4:
            cout << tree.nth(k) << '\n';
            break;
        case 5:
            cout << tree.prec(k) << '\n';
            break;
        case 6:
            cout << tree.succ(k) << '\n';
            break;
        default:
            break;
        }
    }
    return 0;
}

2024/6/20 19:38
加载中...