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 }

 

posted @ 2017-03-11 18:03  Robin!  阅读(180)  评论(0编辑  收藏  举报