BST-Treap数组实现板子 Ver1.0

Posted bringlu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BST-Treap数组实现板子 Ver1.0相关的知识,希望对你有一定的参考价值。

这里只有板子没有原理QWQ
可实现
1.插入 x 数
2.删除 x 数(若有多个相同的数,只删除一个)
3.查询 x 数的排名(排名定义为比当前数小的数的个数 +1)
4.查询排名为 x 的数
5.求 x 的前驱(前驱定义为小于 x,且最大的数)
6.求 x 的后继(后继定义为大于 x,且最小的数)
原题 https://www.luogu.com.cn/problem/P3369 374ms 2.78MB

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define IL  inline
typedef long long LL;

const int N = 1e5 + 3;

struct Node {
    int ch[2],v,sz,r,cnt;
    IL bool operator < (const Node& rhs) const { return r < rhs.r;}
    IL int cmp(int x) const {
        if(x == v) return -1;
        return x > v;
    }
};
struct Treap {
    int sz,root,ans;
    Node tr[N];
    IL void init() {tr[0].ch[0]=tr[0].ch[1]=tr[0].sz=tr[0].cnt=tr[0].r=0; root = 0;}
    IL void upd(int o) { tr[o].sz=tr[tr[o].ch[0]].sz+tr[tr[o].ch[1]].sz+tr[o].cnt;}
    IL void rotate(int &o,int d) {
        int k = tr[o].ch[d^1]; tr[o].ch[d^1]=tr[k].ch[d]; tr[k].ch[d] = o;
        upd(o); upd(k); o = k;
    }
    void insert(int &o,int x) {
        if(o == 0) {
            o=++sz;
            tr[o].ch[0] = tr[o].ch[1] = 0;
            tr[o].sz = tr[o].cnt=1;
            tr[o].v = x; tr[o].r = rand();
            return;
        }
        tr[o].sz++;
        int d = tr[o].cmp(x);
        if(d == -1) { tr[o].cnt++; return;}
        insert(tr[o].ch[d],x);
        if(tr[tr[o].ch[d]].r > tr[o].r) rotate(o,d^1);
        upd(o);
    }
    void erase(int &o,int x) {
        if(o == 0) return;
        int d = tr[o].cmp(x);
        if(d == -1) {
            if(tr[o].cnt > 1) { tr[o].cnt--; tr[o].sz--; return;}
            if(tr[o].ch[0]*tr[o].ch[1]==0) { o = tr[o].ch[0] + tr[o].ch[1];}
            else {
                int d2 = tr[tr[o].ch[0]].r > tr[tr[o].ch[1]].r;
                rotate(o,d2); erase(tr[o].ch[d2],x);
            }
        }
        else erase(tr[o].ch[d],x);
        upd(o);
    }
    int query_rank(int o,int x) { //查询x的排名 
        if(o == 0) return 0;
        if(tr[o].v==x) return tr[tr[o].ch[0]].sz+1;
        else if(x > tr[o].v) 
            return tr[tr[o].ch[0]].sz+tr[o].cnt+query_rank(tr[o].ch[1],x);
        else return query_rank(tr[o].ch[0],x);
    }
    int query_kth(int o,int x) { //查询排名为x的数 
        if(o == 0) return 0;
        if(x <= tr[tr[o].ch[0]].sz) return query_kth(tr[o].ch[0],x);
        else if(x>tr[tr[o].ch[0]].sz+tr[o].cnt)
            return query_kth(tr[o].ch[1],x-tr[tr[o].ch[0]].sz-tr[o].cnt);
        else return tr[o].v;     
    }
    void query_pre(int o,int x) { // 查询x的前驱 
        if(o == 0) return;
        if(tr[o].v < x) {
            ans = o; query_pre(tr[o].ch[1],x);
        }
        else query_pre(tr[o].ch[0],x);
    }
    void query_sub(int o,int x) { // 查询x的后继 
        if(o == 0) return;
        if(tr[o].v > x) {
            ans = o; query_sub(tr[o].ch[0],x);
        }
        else query_sub(tr[o].ch[1],x);
    }
    IL void ins(int x) {insert(root,x); return;}
    IL void del(int x) {erase(root,x); return;}
    IL int rank(int x) {return query_rank(root,x);} //return rank of x
    IL int kth(int x) {return query_kth(root,x);} // return the number,which rank=x.
    IL int pre(int x) {ans=0; query_pre(root,x); return ans;}
    IL int sub(int x) {ans=0; query_sub(root,x); return ans;}
};

Treap tr;
int main() {
    int n; scanf("%d",&n);
    int op,x;
    tr.init();
    for(int i=0;i<n;i++) {
        scanf("%d%d",&op,&x);
        switch(op) {
            case 1: tr.ins(x); break;
            case 2: tr.del(x); break;
            case 3: printf("%d
",tr.rank(x)); break;
            case 4: printf("%d
",tr.kth(x)); break;
            case 5: printf("%d
",tr.tr[tr.pre(x)].v); break;
            case 6: printf("%d
",tr.tr[tr.sub(x)].v); break;
        }
    }
}

以上是关于BST-Treap数组实现板子 Ver1.0的主要内容,如果未能解决你的问题,请参考以下文章

全国大学生智能车介绍-VER1.0 | 陈桂友

树状数组板子

u-boot for tiny210 ver1.0(by liukun321咕唧咕唧)

在并行位片代码中实现快速计数器

主席树板子二

1908-逆序对(归并板子)