HYSBZ - 3224 Tyvj 1728 普通平衡树——treap

比splay快了300ms

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 2147483647;
const int INF = 0x3f3f3f3f;
struct Treap {
    int seed, sz, root, ch[maxn][2], val[maxn], key[maxn], cnt[maxn], size[maxn];
    void clear() { seed = 2333; sz = root = 0; }
    int rand() { return seed = (int)(seed*482411LL%mod); }
    void newnode(int x, int v) {
        ch[x][0] = ch[x][1] = 0, val[x] = v, key[x] = rand(); cnt[x] = size[x] = 1;
    }
    void pushup(int x) {
        if (!x) return;
        size[x] = cnt[x];
        if (ch[x][0]) size[x] += size[ch[x][0]];
        if (ch[x][1]) size[x] += size[ch[x][1]];
    }
    void zag(int &x) {
        int t = ch[x][1];
        ch[x][1] = ch[t][0]; ch[t][0] = x; size[t] = size[x]; pushup(x); x = t;
    }
    void zig(int &x) {
        int t = ch[x][0];
        ch[x][0] = ch[t][1]; ch[t][1] = x; size[t] = size[x]; pushup(x); x = t;
    }
    void insert(int &x, int v) {
        if (!x) { newnode((x=++sz), v); return; }
        size[x]++;
        if (v == val[x]) cnt[x]++;
        else if (v < val[x]) {
            insert(ch[x][0], v);
            if (key[ch[x][0]] < key[x]) zig(x);
        }
        else {
            insert(ch[x][1], v);
            if (key[ch[x][1]] < key[x]) zag(x);
        }
    }
    void delet(int &x, int v) {
        if (!x) return;
        if (v == val[x]) {
            if (cnt[x] > 1) cnt[x]--, size[x]--;
            else {
                if (!ch[x][0]||!ch[x][1]) x = ch[x][0]+ch[x][1];
                else if (key[ch[x][0]] < key[ch[x][1]]) {
                    zig(x); delet(x, v);
                }
                else {
                    zag(x); delet(x, v);
                }
            }
        }
        else if (v < val[x]) { size[x]--; delet(ch[x][0], v); }
        else { size[x]--; delet(ch[x][1], v); }
    }
    int rank(int v) {
        int ans = 0, x = root;
        while (true) {
            if (!x) return -1;
            if (v < val[x]) x = ch[x][0];
            else {
                ans += (ch[x][0]?size[ch[x][0]]:0);
                if (v == val[x]) return ans + 1;
                ans += cnt[x]; x = ch[x][1];
            }
        }
    }
    int kth(int v) {
        int x = root;
        while (true) {
            if (!x) return -1;
            if (ch[x][0] && size[ch[x][0]] >= v) x = ch[x][0];
            else {
                int t = (ch[x][0] ? size[ch[x][0]] : 0) + cnt[x];
                if (v <= t) return val[x];
                v -= t; x = ch[x][1];
            }
        }
    }
    int pre(int x, int v) {
        if (x == 0) return -INF;
        if (v <= val[x]) return pre(ch[x][0], v);
        else return max(val[x], pre(ch[x][1], v));
    }
    int post(int x, int v) {
        if (x == 0) return INF;
        if (v < val[x]) return min(val[x], post(ch[x][0], v));
        else return post(ch[x][1], v);
    }
}ac;

int main() {
    ac.clear();
    int T;
    scanf("%d", &T);
    while (T--) {
        int opt, x;
        scanf("%d %d", &opt, &x);
        if (opt == 1) ac.insert(ac.root, x);
        else if (opt == 2) ac.delet(ac.root, x);
        else if (opt == 3) printf("%d\n", ac.rank(x));
        else if (opt == 4) printf("%d\n", ac.kth(x));
        else if (opt == 5) printf("%d\n", ac.pre(ac.root, x));
        else printf("%d\n", ac.post(ac.root, x));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/80113597