萌新求助 Treap 36pts
查看原帖
萌新求助 Treap 36pts
610557
shinzanmonoszm 妹妹楼主2023/1/15 10:44
#include<iostream>
#include<random>
#include<limits>
#include<ctime>
std::mt19937_64 rnd(20230115);
const int sz = 1e5 + 10;
using ull = unsigned long long;
const int inf = std::numeric_limits<int>::max();
struct BST {
    struct node {
        int val, cnt, size, lson, rson;
        ull key = std::numeric_limits<ull>::max();
    } tree[sz];
    int num, root;
    void resize(int u) {
        tree[u].size = tree[u].cnt;
        if (tree[u].lson) tree[u].size += tree[tree[u].lson].size; 
        if (tree[u].rson) tree[u].size += tree[tree[u].rson].size;
    }
    void create(int val) {
        tree[num].val = val;
        tree[num].size = tree[num].cnt = 1;
        tree[num].key = rnd();
    }
    void rotateleft(int& p) {
        int tmp = tree[p].rson;
        tree[p].rson = tree[tmp].lson;
        tree[tmp].lson = p;
        resize(p), resize(tmp);
        p = tmp;  
    }
    void rotateright(int& p) {
        int tmp = tree[p].lson;
        tree[p].lson = tree[tmp].rson;
        tree[tmp].rson = p;
        resize(p), resize(tmp);
        p = tmp; 
    }
    void insert(int& pos, int val) {
        if (pos == 0) return pos = ++num, create(val), void();
        if (tree[pos].val == val) return tree[pos].cnt++, tree[pos].size++, void();
        else if (tree[pos].val > val) {
            insert(tree[pos].lson, val);
            if (tree[pos].key > tree[tree[pos].lson].key) rotateright(pos);
            resize(pos);
        } else {
            insert(tree[pos].rson, val);
            if (tree[pos].key > tree[tree[pos].rson].key) rotateleft(pos);
            resize(pos);
        }
    }
    void erase(int& pos, int val) {
        if (tree[pos].val > val) erase(tree[pos].lson, val), resize(pos);
        else if (tree[pos].val < val) erase(tree[pos].rson, val), resize(pos);
        else {
            if (tree[pos].cnt > 1) tree[pos].cnt--, tree[pos].size--; 
            else if (tree[pos].lson == 0 && tree[pos].rson == 0) pos = 0;
            else if (tree[pos].lson && tree[pos].rson) {
                if (tree[tree[pos].lson].key < tree[tree[pos].rson].key) 
                    rotateright(pos), erase(tree[pos].rson, val);
                else rotateleft(pos), erase(tree[pos].lson, val);
                resize(pos);
            } else {
                if (tree[pos].lson) pos = tree[pos].lson;
                else pos = tree[pos].rson;
                resize(pos);
            }
        } 
    }   
    int rank(int pos, int val) {
        int lesscnt = tree[pos].lson == 0 ? 0 : tree[tree[pos].lson].size;
        if (val == tree[pos].val) return lesscnt + 1;
        else if (val < tree[pos].val) {
            if (tree[pos].lson != 0) return rank(tree[pos].lson, val);
            else return 1;
        } else {
            if (tree[pos].rson != 0)
                return lesscnt + tree[pos].cnt + rank(tree[pos].rson, val);
            else return tree[pos].size + 1;
        }
    }
    int kthElement(int pos, int k) {
        int lesscnt = tree[pos].lson == 0 ? 0 : tree[tree[pos].lson].size;
        if (k <= lesscnt) return kthElement(tree[pos].lson, k);
        else if (k <= lesscnt + tree[pos].cnt) return tree[pos].val;
        else return kthElement(tree[pos].rson, k - lesscnt - tree[pos].cnt);
    }
    int prev(int pos, int val) {
        int tmp = -inf;
        if (val <= tree[pos].val) {
            if (tree[pos].lson != 0)
                tmp = prev(tree[pos].lson, val);
        } else {
            tmp = tree[pos].val;
            if (tree[pos].rson != 0) 
                tmp = prev(tree[pos].rson, val);
        }
        if (tmp == -inf || tmp >= val) {
            if (tree[pos].lson != 0)
                tmp = prev(tree[pos].lson, val);
            else
                tmp = prev(tree[pos].rson, val);
        }
        return tmp;
    }
    int post(int pos, int val) {
        int tmp = inf;
        if (val >= tree[pos].val) {
            if (tree[pos].rson != 0)
                tmp = post(tree[pos].rson, val);
        } else {
            tmp = tree[pos].val;
            if (tree[pos].lson != 0) 
                tmp = post(tree[pos].lson, val);
        }
        if (tmp == inf || tmp <= val) {
            if (tree[pos].rson != 0)
                tmp = post(tree[pos].rson, val);
            else
                tmp = post(tree[pos].lson, val);
        }
        return tmp;
    }
} treap;
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n;
    std::cin >> n;
    while (n--) {
        int op, val;
        std::cin >> op >> val;
        switch (op) {
            case 1:
                treap.insert(treap.root, val);
                break;
            case 2:
                treap.erase(treap.root, val);
                break;
            case 3:
                std::cout << treap.rank(treap.root, val) << "\n";
                break;
            case 4:
                std::cout << treap.kthElement(treap.root, val) <<"\n";
                break;
            case 5:
                std::cout << treap.prev(treap.root, val) << "\n";
                break;
            case 6:
                std::cout << treap.post(treap.root, val) << "\n";
                break;
        }
    }
    return 0;
}
2023/1/15 10:44
加载中...