FhqTreap求调,玄关,码风优良,有注释。
查看原帖
FhqTreap求调,玄关,码风优良,有注释。
623557
Leaper_lyc楼主2025/2/6 19:38

20pts,只过了 #1 和 #6

#include <bits/stdc++.h>
using namespace std;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
const int N = 1e5 + 10;
struct node {
    int ls, rs, val, rdv, siz;
} tr[N];
int node_cnt, cnt = 0;
#define ls(p) tr[p].ls
#define rs(p) tr[p].rs
#define val(p) tr[p].val
#define rdv(p) tr[p].rdv
#define siz(p) tr[p].siz
struct FhqTreap {
    int _root;
    inline int new_node(int v) {
        int p = ++node_cnt;
        ls(p) = rs(p) = 0, val(p) = v, rdv(p) = rnd(), siz(p) = 1;
        return p;
    }
    inline void split_val(int p, int k, int &lt, int &rt) {
        if (!p) return lt = rt = 0, void();
        if (val(p) <= k) {
            lt = p;
            split_val(rs(p), k, rs(lt), rt);
        } else {
            rt = p;
            split_val(ls(p), k, lt, ls(rt));
        }
        siz(p) = siz(ls(p)) + siz(rs(p)) + 1;
    }
    inline void split_size(int p, int k, int &lt, int &rt) {
        if (!p) return lt = rt = 0, void();
        if (siz(ls(p)) + 1 <= k) {
            lt = p;
            split_size(rs(p), k - siz(ls(p)) - 1, rs(lt), rt);
        } else {
            rt = p;
            split_size(ls(p), k, lt, ls(rt));
        }
        siz(p) = siz(ls(p)) + siz(rs(p)) + 1;
    }
    inline int merge(int lt, int rt) {
        if (!lt || !rt) return lt | rt;
        if (rdv(lt) > rdv(rt)) {
            rs(lt) = merge(rs(lt), rt);
            siz(lt) = siz(ls(lt)) + siz(rs(lt)) + 1;
            return lt;
        } else {
            ls(rt) = merge(lt, ls(rt));
            siz(rt) = siz(ls(rt)) + siz(rs(rt)) + 1;
            return rt;
        }
    }
    inline void Insert(int k) {
        int p1 = 0, p2 = 0;
        split_val(_root, k, p1, p2);
        _root = merge(merge(p1, new_node(k)), p2);
    }
    inline int qMax(int p) {
        if (!rs(p)) return val(p);
        return qMax(rs(p));
    }
    inline int qKth(int k) { // 询问第 k 小
        if (k < 1 || k > siz(_root)) return -1;
        int p1 = 0, p2 = 0;
        split_size(_root, k, p1, p2);
        int res = qMax(p1);
        _root = merge(p1, p2);
        return res;
    }
    inline void Delete(int k) { // 删除小于等于 k 的部分
        int p1 = 0, p2 = 0;
        split_val(_root, k, p1, p2);
        cnt += siz(p1);
        _root = p2;
    }
} T;
int q, Beg, Add; // Beg 表示最低工资,Add 表示全局加标记
signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> q >> Beg; Add = 0;
    while (q--) {
        char op; int k;
        cin >> op >> k;
        if (op == 'I') {
            k -= Add;
            T.Insert(k);
        } else if (op == 'A') {
            Add += k;
        } else if (op == 'S') {
            Add -= k;
            T.Delete(Beg - Add - 1);
        } else {
            int res = T.qKth(siz(T._root) - k + 1); // 询问第 k 大,所以是 siz - k + 1
            if (res > 0) cout << res + Add << '\n';
            else cout << "-1\n";
        }
    }
    cout << cnt << '\n';
}
2025/2/6 19:38
加载中...