洛谷P3369 模板 普通平衡树 (Treap)

洛谷P3369 模板 普通平衡树 (Treap)

title

/*
Treap
*/



#include <cstdio>
#include <cstdlib>

using namespace std;

const int N = 100010;

struct Treap {

    int l[N], r[N], d[N], siz[N], cnt[N], val[N];
    int tot, rt, ERR;



    int mk(int v) {
        val[++tot] = v;
        d[tot] = rand();
        siz[tot] = 1;
        cnt[tot] = 1;
        return tot;
    }

    int update(int x) {
        return siz[x] = siz[l[x]] + siz[r[x]] + cnt[x];
    }

    int leftRotate(int &x) {
        int tmp = r[x];
        r[x] = l[tmp];
        l[tmp] = x;
        x = tmp;
        update(l[x]);
        update(x);
        return x;
    }

    int rightRotate(int &x) {
        int tmp = l[x];
        l[x] = r[tmp];
        r[tmp] = x;
        x = tmp;
        update(r[x]);
        update(x);
        return x;
    }

    void insert(int &x, int v) {
        if (!x) {
            x = mk(v);
            return ;
        }
        if (v == val[x]) ++cnt[x];
        else {
            if (v < val[x]) {
                insert(l[x], v);
                if (d[x] < d[l[x]])
                    rightRotate(x);
            } else {
                insert(r[x], v);
                if (d[x] < d[r[x]])
                    leftRotate(x);
            }
        }
        update(x);
        return ;
    }

    void erase(int &x, int v) {
        if (!x) return ;
        if (v == val[x]) {
            if (cnt[x] > 1) --cnt[x], update(x);
            else if (!l[x] && !r[x]) x = 0;
            else {
                if (!r[x] || d[r[x]] < d[l[x]]) rightRotate(x), erase(r[x], v);
                else leftRotate(x), erase(l[x], v);
                update(x);
            }
            return ;
        }
        if (v < val[x]) erase(l[x], v);
        else erase(r[x], v);
        update(x);
        return ;
    }

    void del(int &x, int v) {
        if (!x) return ;
        if (v == val[x]) {
            cnt[x] = 1, update(x);
            if (!l[x] && !r[x]) x = 0;
            else {
                if (!r[x] || d[r[x]] < d[l[x]]) rightRotate(x), del(r[x], v);
                else leftRotate(x), del(l[x], v);
                update(x);
            }
            return ;
        }
        if (v < val[x]) del(l[x], v);
        else del(r[x], v);
        update(x);
        return ;
    }

    int clear(int error) {
        rt = tot = 0;
        return ERR = error;
    }

    int error() {
        return ERR;
    }

    int size() {
        return siz[rt];
    }

    bool empty() {
        return !siz[rt];
    }

    void insert(int x) {
        insert(rt, x);
        return ;
    }

    void erase(int x) {
        erase(rt, x);
        return ;
    }

    void del(int x) {
        del(rt, x);
        return ;
    }

    int rank(int v) {
        int x, ans = 0;
        for (x = rt; x;) {
            if (v < val[x]) x = l[x];
            else if (v > val[x]) ans += siz[l[x]] + cnt[x], x = r[x];
            else return ans + siz[l[x]] + 1;
        }
        return ans + 1;
    }

    int value(int v) {
        int x;
        for (x = rt; x;) {
            if (v <= siz[l[x]]) x = l[x];
            else if (v <= siz[l[x]] + cnt[x]) return val[x];
            else v -= siz[l[x]] + cnt[x], x = r[x];
        }
        return ERR;
    }

    bool find(int v) {
        int x;
        for (x = rt; x;) {
            if (v < val[x]) x = l[x];
            else if (v > val[x]) x = r[x];
            else return 1;
        }
        return 0;
    }

    int count(int v) {
        int x;
        for (x = rt; x;) {
            if (v < val[x]) x = l[x];
            else if (v > val[x]) x = r[x];
            else return cnt[x];
        }
        return ERR;
    }

    int pre(int v) {
        int res = ERR;
        for (int x = rt; x;)
            if (val[x] < v) res = val[x], x = r[x];
            else x = l[x];
        return res;
    }

    int nxt(int v) {
        int res = ERR;
        for (int x = rt; x;)
            if (val[x] > v) res = val[x], x = l[x];
            else x = r[x];
        return res;
    }

    int max() {
        int x;
        for (x = rt; r[x]; x = r[x]);
        return val[x];
    }

    int min() {
        int x;
        for (x = rt; l[x]; x = l[x]);
        return val[x];
    }



    /*
    int clear(int error)
        init the treap, the error result is error
        return the error

    int error()
        return the error

    int size()
        return how many numbers in treap

    bool empty()
        return true or false
        true : the treap is empty
        false : the treap isn't empty

    void insert(int x)
        insert x to the treap

    void erase(int x)
        delete x in the treap

    void del(int x)
        delete all x in the treap
        
    int rank(int v)
        return v 's rank

    int value(int v)
        return the vth small number

    bool find(int v)
        return true or false
        true : v is in the treap
        false : v isn't in the treap

    int count(int v)
        return how many v in the treap

    int pre(int v)
        return x
        x < v
        x is the biggest

    int nxt(int v)
        return x
        x > v
        x is the smallest

    int max()
        return x
        x is the biggest

    int min()
        return x
        x is the smallest
    */
};

Treap t;

int main() {
    int q, opt, x;
    t.clear(0);
    for (scanf("%d", &q); q; --q) {
        scanf("%d %d", &opt, &x);
        if (opt == 1) t.insert(x);
        else if (opt == 2) t.erase(x);
        else if (opt == 3) printf("%d\n", t.rank(x));
        else if (opt == 4) printf("%d\n", t.value(x));
        else if (opt == 5) printf("%d\n", t.pre(x));
        else printf("%d\n", t.nxt(x));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值