[BZOJ3224] [Tyvj 1728] 普通平衡树 (treap)

Description

  您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
  1. 插入x数
  2. 删除x数(若有多个相同的数,因只删除一个)
  3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
  4. 查询排名为x的数
  5. 求x的前驱(前驱定义为小于x,且最大的数)
  6. 求x的后继(后继定义为大于x,且最小的数)

Input

  第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

  对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

  1.n的数据范围:n<=100000
  2.每个数的数据范围:[-1e7,1e7]

Source

  平衡树

Solution

  哦,这道题几乎涵盖了treap所有操作。然后窝写挂了好~~~长时间

  话说BZOJ1500窝是不是AC无望QAQ

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 struct treap
  4 {
  5     int l, r, siz, key, val, pri;
  6 }a[100005];
  7 int root, ptot, ans;
  8  
  9 void push_up(int k)
 10 {
 11     a[k].siz = a[a[k].l].siz + a[a[k].r].siz + a[k].val;
 12 }
 13  
 14 void lturn(int &k)
 15 {
 16     int tmp = a[k].r;
 17     a[k].r = a[tmp].l, a[tmp].l = k;
 18     a[tmp].siz = a[k].siz, push_up(k), k = tmp;
 19 }
 20  
 21 void rturn(int &k)
 22 {
 23     int tmp = a[k].l;
 24     a[k].l = a[tmp].r, a[tmp].r = k;
 25     a[tmp].siz = a[k].siz, push_up(k), k = tmp;
 26 }
 27  
 28 void insert(int &k, int x)
 29 {
 30     if(!k)
 31     {
 32         k = ++ptot, a[k].siz = a[k].val = 1;
 33         a[k].key = x, a[k].pri = rand();
 34         return;
 35     }
 36     a[k].siz++;
 37     if(x == a[k].key) a[k].val++;
 38     else if(x < a[k].key)
 39     {
 40         insert(a[k].l, x);
 41         if(a[k].pri < a[a[k].l].pri) rturn(k);
 42     }
 43     else
 44     {
 45         insert(a[k].r, x);
 46         if(a[k].pri < a[a[k].r].pri) lturn(k);
 47     }
 48 }
 49  
 50 void del(int &k, int x)
 51 {
 52     if(!k) return;
 53     if(x == a[k].key)
 54         if(a[k].val > 1) a[k].val--, a[k].siz--;
 55         else if(!(a[k].l * a[k].r)) k = a[k].l + a[k].r;
 56         else if(a[a[k].l].pri < a[a[k].r].pri)
 57             lturn(k), del(k, x);
 58         else rturn(k), del(k, x);
 59     else if(x < a[k].key) a[k].siz--, del(a[k].l, x);
 60     else a[k].siz--, del(a[k].r, x);
 61 }
 62  
 63 int query_rank(int k, int x)
 64 {
 65     if(!k) return 0;
 66     if(x < a[k].key) return query_rank(a[k].l, x);
 67     if(x == a[k].key) return a[a[k].l].siz + 1;
 68     return a[a[k].l].siz + a[k].val + query_rank(a[k].r, x);
 69 }
 70  
 71 int query_num(int k, int x)
 72 {
 73     if(!k) return 0;
 74     if(x <= a[a[k].l].siz) return query_num(a[k].l, x);
 75     if(x <= a[a[k].l].siz + a[k].val) return a[k].key;
 76     return query_num(a[k].r, x - a[a[k].l].siz - a[k].val);
 77 }
 78  
 79 void query_pro(int k, int x)
 80 {
 81     if(!k) return;
 82     if(x <= a[k].key) query_pro(a[k].l, x);
 83     else ans = a[k].key, query_pro(a[k].r, x);
 84 }
 85  
 86 void query_sub(int k, int x)
 87 {
 88     if(!k) return;
 89     if(x >= a[k].key) query_sub(a[k].r, x);
 90     else ans = a[k].key, query_sub(a[k].l, x);
 91 }
 92  
 93 int main()
 94 {
 95     int n, op, x;
 96     scanf("%d", &n), srand(n);
 97     while(n--)
 98     {
 99         scanf("%d%d", &op, &x);
100         if(op == 1) insert(root, x);
101         if(op == 2) del(root, x);
102         if(op == 3) printf("%d\n", query_rank(root, x));
103         if(op == 4) printf("%d\n", query_num(root, x));
104         if(op == 5) ans = 0, query_pro(root, x), printf("%d\n", ans);
105         if(op == 6) ans = 0, query_sub(root, x), printf("%d\n", ans);
106     }
107     return 0;
108 }
View Code

 

posted @ 2016-05-01 22:00  CtrlCV  阅读(204)  评论(0编辑  收藏  举报