精华

普通平衡树

YIZHIYANG初来乍到 2026-6-7 12:03:39 35 浏览 1 点赞 0 收藏
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 100005;

int n, rt, tot;
int ch[N][2], sz[N], va[N];
unsigned ky[N], sd = 71236721;

unsigned rd() {
    sd ^= sd << 13;
    sd ^= sd >> 17;
    sd ^= sd << 5;
    return sd;
}

int nw(int v) {
    ++tot;
    va[tot] = v;
    sz[tot] = 1;
    ky[tot] = rd();
    return tot;
}

void pu(int x) {
    sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
}

void sp(int u, int v, int &x, int &y) {
    if (!u) {
        x = y = 0;
        return;
    }

    if (va[u] <= v) {
        x = u;
        sp(ch[u][1], v, ch[u][1], y);
        pu(x);
    } else {
        y = u;
        sp(ch[u][0], v, x, ch[u][0]);
        pu(y);
    }
}

int mg(int x, int y) {
    if (!x || !y) return x + y;

    if (ky[x] < ky[y]) {
        ch[x][1] = mg(ch[x][1], y);
        pu(x);
        return x;
    } else {
        ch[y][0] = mg(x, ch[y][0]);
        pu(y);
        return y;
    }
}

void ins(int v) {
    int a, b;
    sp(rt, v, a, b);
    rt = mg(mg(a, nw(v)), b);
}

void del(int v) {
    int a, b, c;

    sp(rt, v, a, c);
    sp(a, v - 1, a, b);

    if (b) b = mg(ch[b][0], ch[b][1]);

    rt = mg(mg(a, b), c);
}

int kth(int u, int k) {
    while (1) {
        int lz = sz[ch[u][0]];

        if (k <= lz) u = ch[u][0];
        else if (k == lz + 1) return va[u];
        else {
            k -= lz + 1;
            u = ch[u][1];
        }
    }
}

int rk(int v) {
    int a, b;

    sp(rt, v - 1, a, b);

    int an = sz[a] + 1;

    rt = mg(a, b);
    return an;
}

int pre(int v) {
    int a, b;

    sp(rt, v - 1, a, b);

    int an = kth(a, sz[a]);

    rt = mg(a, b);
    return an;
}

int nxt(int v) {
    int a, b;

    sp(rt, v, a, b);

    int an = kth(b, 1);

    rt = mg(a, b);
    return an;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n;

    while (n--) {
        int op, x;
        cin >> op >> x;

        if (op == 1) ins(x);
        else if (op == 2) del(x);
        else if (op == 3) cout << rk(x) << "\n";
        else if (op == 4) cout << kth(rt, x) << "\n";
        else if (op == 5) cout << pre(x) << "\n";
        else cout << nxt(x) << "\n";
    }

    return 0;
}

评论

0 条
还没有评论。