• Treap实现名次树


    Treap(树堆)的大部分功能STL的set都可以实现,但因为set的过度封装使得某些特定的功能不能实现,比如求第k大的值。

    Code:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 1000 + 10;
      4 
      5 struct node {
      6     node *ch[2];
      7     int r;
      8     int v;
      9     int s;
     10     node (int v):v(v) {ch[0] = ch[1] = NULL; r = rand(); s = 1;}
     11     bool operator < (const node& rhs) const {
     12         return r < rhs.r;
     13     }
     14     int cmp(int x) const{
     15         if (x == v) return -1;
     16         return x < v ? 0 : 1;
     17     }
     18     void maintain() {
     19         s = 1;
     20         if (ch[0] != NULL) s += ch[0]->s;
     21         if (ch[1] != NULL) s += ch[1]->s;
     22     }
     23 };
     24 
     25 void rotate(node* &o, int d) {
     26     node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; 
     27     k->ch[d] = o; o->maintain(); k->maintain(); o = k;
     28 }
     29 
     30 int find(node* o, int x) {
     31     while(o != NULL) {
     32         int d = o->cmp(x);
     33         if (d == -1) return 1;
     34         else o = o->ch[d];
     35     }
     36     return 0;
     37 }
     38 
     39 void insert(node* &o, int x) {
     40     if (o == NULL) {
     41         o = new node(x);
     42         o->ch[0] = o->ch[1] = NULL;
     43         o->v = x;
     44     }
     45     else {
     46         int d = (x < o->v ? 0 : 1);
     47         insert(o->ch[d], x);
     48         if (o->ch[d]->r > o->r) rotate(o, d^1);
     49     }
     50     o->maintain();
     51 }
     52 
     53 void remove(node* &o, int x) {
     54     int d = o->cmp(x);
     55     if (d == -1) {
     56         if (o->ch[0] == NULL) o = o->ch[1];
     57         else if (o->ch[1] == NULL) o = o->ch[0];
     58         else {
     59             int d2 = o->ch[0]->r > o->ch[1]->r ? 1 : 0;
     60             rotate(o, d2); remove(o->ch[d2], x);
     61         }
     62     }
     63     else remove(o->ch[d], x); 
     64     if (o != NULL) o->maintain();
     65 }
     66 
     67 int kth(node* &o, int k) {
     68     if (o == NULL || k <= 0 || k > o->s) return 0;
     69     int s = (o->ch[1] == NULL ? 0 : o->ch[1]->s);
     70     if (k == s + 1) return o->v;
     71     else if (k <= s) return kth(o->ch[1], k);
     72     else return kth(o->ch[0], k-s-1);
     73 }
     74 
     75 int main() {
     76     int a, k;
     77     char op[10];
     78     node *rt = NULL;
     79     while(cin >> op, op[0] != 'E') {
     80         switch(op[0]) {
     81             case 'i':
     82                 cin >> a;
     83                 if (find(rt, a)) {
     84                     cout << a << " is in Treap" << endl;
     85                     break;
     86                 }
     87                 insert(rt, a);
     88                 break;
     89             case 'r':
     90                 cin >> a;
     91                 if (!find(rt, a)) {
     92                     cout << a << " isn't in Treap" << endl;
     93                     break;
     94                 }
     95                 remove(rt, a);
     96                 break;
     97             case 'q':
     98                 cin >> k;
     99                 a = kth(rt, k);
    100                 if (a) cout << "The " << k << "th is " << a << endl;
    101                 else cout << "error" << endl;
    102                 break;
    103         }
    104     }
    105 
    106     return 0;
    107 }
  • 相关阅读:
    CoreData和SQLite多线程访问时的线程安全问题
    JSPatch 实现原理详解
    iOS开发工程师必备技能(持续更新)
    iOS音频播放、录音、视频播放、拍照、视频录制
    使用MVVM减少控制器代码实战(减少56%)
    如何结合场景利用block进行回调
    Masonry框架源码深度解析
    Ubantu编译安装FFmpeg
    HTTP Live Streaming网络视频直播调研
    RHEL/CentOS 6的更新源
  • 原文地址:https://www.cnblogs.com/robin1998/p/6535729.html
Copyright © 2020-2023  润新知