社区讨论

MnZn求助,指针Treap莫名部分RE

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

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@lo8y58qi
此快照首次捕获于
2023/10/28 02:28
2 年前
此快照最后确认于
2023/10/28 02:28
2 年前
查看原帖
CPP
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <string>
#include <random>
#include <ctime>
#include <climits>
typedef long long ll;
typedef std::pair<int, int> pii;

template <class T = int, T error = -1>
class Treap {
private:
    struct node {
        node* ch[2];
        int r, s, cnt;
        T v;
        int cmp(T x) {
            if (x == v) return -1;
            return x < v ? 0 : 1;
        }
        void maintain() {
            s = (ch[0] == NULL ? 0 : ch[0] -> s ) + (ch[1] == NULL ? 0 : ch[1] -> s ) + cnt;
        }
    };
    void rotate(node* &o, int d) {
        node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o;
        o -> maintain(); k -> maintain(); o = k;
    }
public:
    node* root = nullptr;
    void insert(node* &o, T x) {
        if (o == nullptr) {
            o = new node(); o -> cnt = 1; o -> ch[0] = o -> ch[1] = nullptr; o -> v = x; o -> r = rand();
        }
        else {
            int d = o -> cmp(x);
            if (d == -1) o -> cnt ++;
            else {
                insert(o -> ch[d], x);
                if (o -> ch[d] -> r > o -> r) rotate(o, d ^ 1);
            }
        }
        o -> maintain();
    }
    void remove(node* &o, T x) {
        int d = o -> cmp(x);
        if (d == -1) {
            if (o -> ch[0] == nullptr) o = o -> ch[1];
            else if (o -> ch[1] == nullptr) o = o -> ch[0];
            else {
                int d2 = (o -> ch[0] > o -> ch[1] ? 1 : 0);
                rotate(o, d2); remove(o -> ch[d2], x);
            }
        }
        else remove(o -> ch[d], x);
        if (o != nullptr) o -> maintain();
    }
    bool find(node* o, T x) {
        while (o != nullptr) {
            int d = o -> cmp(x);
            if (d == -1) return true;
            else o = o -> ch[d];
        }
        return false;
    }
    T kth(node* o, int k) {
        if (o == nullptr || k <= 0 || k > o -> s) return error;
        int s = (o -> ch[0] == nullptr ? 0 : o -> ch[0] -> s);
        if (k >= s + 1 && k <= s + o -> cnt) return o -> v;
        else if (k <= s) return kth(o -> ch[0], k);
        else return kth(o -> ch[1], k - s - o -> cnt);
    }
    int rank(node* o, T k) {
        if (o == nullptr) return 0;
        int s = (o -> ch[0] == nullptr ? 0 : o -> ch[0] -> s);
        if (o -> v == k) return s + 1;
        if (o -> v < k) return s + o -> cnt + rank(o -> ch[1], k);
        return rank(o -> ch[0], k);
    }
    T pre(node *o, T k) {
        int p = error;
        while (o != nullptr) {
            int d = o -> cmp(k);
            if (d == 0 || d == -1) o = o -> ch[0];
            else { p = o -> v; o = o -> ch[1]; }
        }
        return p;
    }
    T post(node *o, T k) {
        int p = error;
        while (o != nullptr) {
            int d = o -> cmp(k);
            if (d == 1 || d == -1) o = o -> ch[1];
            else { p = o -> v; o = o -> ch[0]; }
        }
        return p;
    }
};

Treap<int, INT_MAX> t;

int main() {
    std :: ios :: sync_with_stdio(false);
    std :: cin.tie(nullptr);
    std :: cout.tie(nullptr);
    int n;
    std::cin >> n;
    while (n --) {
        int opt, x;
        std::cin >> opt >> x;
        switch(opt) {
            case 1: t.insert(t.root, x); break;
            case 2: t.remove(t.root, x); break;
            case 3: std :: cout << t.rank(t.root, x) << '\n'; break;
            case 4: std :: cout << t.kth(t.root, x) << '\n'; break;
            case 5: std :: cout << t.pre(t.root, x) << '\n'; break;
            case 6: std :: cout << t.post(t.root, x) << '\n'; break;
        }
    }
    return 0;
}

回复

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

正在加载回复...