fhq treap

祭学会fhq treap
下次有需要再补上 先存个模板

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace  std;
const int N = 1e6 + 10;
int root, n, a, x, y, z, op, Size, siz[N], val[N], rd[N], ch[N][3]; 

inline int read() {
    char ch; bool f = false; int res = 0;
    while (((ch = getchar()) < '0' || ch > '9') && ch != '-');
    if (ch == '-') f = true; else res = ch - '0';
    while ((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + (ch ^ 48);
    return f? ~res + 1 : res;
}

inline void pushup (int x) {
    siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
}

inline int New (int x) {
    siz[++Size] = 1, val[Size] = x, rd[Size] = rand();
    return Size;
}

void split (int p, int &x, int &y, int a) {
    if (p == 0) x = y = 0;
    else {
        if (val[p] <= a) {
            x = p;
            split(ch[p][1], ch[p][1], y, a);
        }
        else {
            y = p;
            split(ch[p][0], x, ch[p][0], a);
        }
        pushup(p);
    }
}

int merge (int a, int b) {
    if (a == 0 || b == 0)
        return a + b;
    if (rd[a] < rd[b]) {
        ch[a][1] = merge(ch[a][1], b);
        pushup(a);
        return a;
    }
    else  {
        ch[b][0] = merge(a, ch[b][0]);
        pushup(b);
        return b;
    }
}

inline int kth (int x, int a) {
    while (true) {
        if (a <= siz[ch[x][0]])
            x = ch[x][0];
        else if (a == siz[ch[x][0]] + 1)
            return x;
        else a -= siz[ch[x][0]] + 1, x = ch[x][1];
    }
}

int main() {
    srand(time(0));
    n = read();
    for (int i = 1; i <= n; i++) {
        op = read(), a = read();
        if (op == 1) { // insert
            split(root, x, y, a);
            root = merge(merge(x, New(a)), y);
        }
        else if (op == 2) { // delete
            split(root, x, z, a);
            split(x, x, y, a - 1);
            y = merge(ch[y][0], ch[y][1]);
            root = merge(merge(x, y), z);
        }
        else if (op == 3) { // rank
            split(root, x, y, a - 1);
            printf("%d\n", siz[x] + 1);
            root = merge(x, y);
        }
        else if (op == 4) { // xth
            printf("%d\n", val[kth(root, a)]);
        }
        else if (op == 5) { // pred
            split(root, x, y, a - 1);
            printf("%d\n", val[kth(x, siz[x])]);
            root = merge(x, y);
        }
        else if (op == 6) { // succ
            split(root, x, y, a);
            printf("%d\n", val[kth(y, 1)]);
            root = merge(x, y);
        }
    }
    return 0;
}
posted @ 2019-07-11 18:01  Trimsteanima  阅读(157)  评论(0编辑  收藏  举报
Live2D