社区讨论

58 pts WA 7-12(替罪羊树)

P3369【模板】普通平衡树参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mhjic5da
此快照首次捕获于
2025/11/04 03:02
4 个月前
此快照最后确认于
2025/11/04 03:02
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
#define N 100005
#define ALPHA 0.75
using namespace std;

int root, idx;
struct Node {
    int ls, rs;
    int val;
    int size; // 子树实际存储数值的结点数量
    int tot;  // 子树总节点数(包括删除的)
    int del;  // 标记是否被删除
} t[N];

void init_node(int u, int x) {
    t[u].ls = t[u].rs = 0;
    t[u].val = x;
    t[u].size = t[u].tot = 1;
    t[u].del = 1;
}

bool not_balance(int u) {
    return max(t[t[u].ls].tot, t[t[u].rs].tot) > ALPHA * t[u].tot;
}

vector<int> nodes;
void collect_nodes(int u) {
    if (!u) return;
    collect_nodes(t[u].ls);
    if (t[u].del) nodes.push_back(u);
    collect_nodes(t[u].rs);
}

void build(int l, int r, int &u) {
    if (l > r) {
        u = 0;
        return;
    }
    int mid = (l + r) >> 1;
    u = nodes[mid];
    build(l, mid - 1, t[u].ls);
    build(mid + 1, r, t[u].rs);
    t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
    t[u].tot = t[t[u].ls].tot + t[t[u].rs].tot + 1;
}

void rebuild(int &u) {
    nodes.clear();
    collect_nodes(u);
    build(0, nodes.size() - 1, u);
}

void insert(int &u, int x) {
    if (!u) {
        u = ++idx;
        init_node(u, x);
        return;
    }
    t[u].size++;
    t[u].tot++;
    if (x <= t[u].val) insert(t[u].ls, x);
    else insert(t[u].rs, x);
    if (not_balance(u)) rebuild(u);
}

int rank1(int u, int x) {
    if (!u) return 0;
    if (x <= t[u].val) return rank1(t[u].ls, x);
    return t[t[u].ls].size + t[u].del + rank1(t[u].rs, x);
}

void del_k(int &u, int k) {
    t[u].size--;
    int left_size = t[t[u].ls].size;
    if (t[u].del && k == left_size + 1) {
        t[u].del = 0;
        return;
    }
    if (k <= left_size + t[u].del) del_k(t[u].ls, k);
    else del_k(t[u].rs, k - left_size - t[u].del);
}

void del(int x) {
    int k = rank1(root, x) + 1;
    del_k(root, k);
    if (t[root].tot * ALPHA > t[root].size) rebuild(root);
}

int kth(int u, int k) {
    int left_size = t[t[u].ls].size;
    if (k <= left_size) return kth(t[u].ls, k);
    if (k == left_size + 1 && t[u].del) return t[u].val;
    return kth(t[u].rs, k - left_size - t[u].del);
}

int pre(int u, int x) {
    if (!u) return INT_MIN;
    if (t[u].val >= x) return pre(t[u].ls, x);
    int res = pre(t[u].rs, x);
    return t[u].del ? max(t[u].val, res) : res;
}

int suc(int u, int x) {
    if (!u) return INT_MAX;
    if (t[u].val <= x) return suc(t[u].rs, x);
    int res = suc(t[u].ls, x);
    return t[u].del ? min(t[u].val, res) : res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    while (n--) {
        int opt, x;
        cin >> opt >> x;
        switch (opt) {
            case 1: insert(root, x); break;
            case 2: del(x); break;
            case 3: cout << rank1(root, x) + 1 << "\n"; break;
            case 4: cout << kth(root, x) << "\n"; break;
            case 5: cout << pre(root, x) << "\n"; break;
            case 6: cout << suc(root, x) << "\n"; break;
        }
    }
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...