zoukankan      html  css  js  c++  java
  • 模板——Treap实现名次树

    Treap 是一种通过赋予结点随机权值的一种满足堆性质二叉搜索树,它很好的解决了二叉搜索树顺序插入组成链式的局限性。

    名次树是指在treap的每个结点中添加附加域size,表示以它为根的子树的总结点树

    名次树支持两个操作:
    Kth(x): 找出第k小(第k大)的元素。

    Rank(x): 值x的名次,即比x小(大)的结点个数加 1 。

    以第k大为例,代码如下:

     1 struct Node {
     2     Node *ch[2];
     3     int r; //随机权值
     4     int v; //值
     5     int s; //附加域size
     6     Node(int vv): v(vv) {
     7         s = 1;
     8         ch[0] = ch[1] = NULL;
     9         r = rand();
    10     }
    11     int cmp(int x) const {
    12         if(x == v) return -1;
    13         return x < v ? 0 : 1;
    14     }
    15     void maintain() {
    16         s = 1;
    17         if(ch[0] != NULL) s += ch[0]->s;
    18         if(ch[1] != NULL) s += ch[1]->s;
    19     }
    20 };
    21 
    22 void rotate(Node* &o, int d) { //旋转操作
    23     Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
    24     o->maintain(); k->maintain(); o = k;
    25 }
    26 
    27 void insert(Node* &o, int x) { //插入操作
    28     if(o == NULL) o = new Node(x);
    29     else {
    30         int d = x < o->v ? 0 : 1;  //注意相等时处理方式可以改变  
    31         insert(o->ch[d], x);
    32         if(o->ch[d]->r > o->r) rotate(o, d^1);
    33     }
    34     o->maintain();
    35 }
    36 void remove(Node* &o, int x) { //删除操作
    37     int d = o->cmp(x);
    38     Node* u = o;
    39     if(d == -1) {
    40         if(o->ch[0] != NULL && o->ch[1] != NULL){
    41             int d2 = o->ch[0]->r > o->ch[1]->r ? 1 : 0;
    42             rotate(o, d2);
    43             remove(o->ch[d2], x);
    44         }
    45         else {
    46             if(o->ch[0] == NULL) o = o->ch[1]; else o = o->ch[0];
    47             delete u;
    48         }
    49     }
    50     else remove(o->ch[d], x);
    51     if(o != NULL) o->maintain();
    52 }
    53 
    54 int kth(Node* o, int k) {  //找第k大
    55     if(o == NULL || k > o->s || k <= 0) return 0;
    56     int s = o->ch[1] == NULL ? 0 : o->ch[1]->s;
    57     if(k == s+1) return o->v;
    58     else if(k <= s) return kth(o->ch[1], k);
    59     else return kth(o->ch[0], k-s-1);
    60 }
  • 相关阅读:
    人脸识别活体检测测试案例
    网络相关配置
    DOS基础整理
    [转载]EXTJS学习
    [转载]JS定时器例子讲解
    [转载]JS定时器例子讲解
    如何设置网页自动刷新(JSP,JS,HTML)
    如何设置网页自动刷新(JSP,JS,HTML)
    18岁以下严禁进入
    18岁以下严禁进入
  • 原文地址:https://www.cnblogs.com/Kiraa/p/6184512.html
Copyright © 2011-2022 走看看