[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
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
84185
492737
HINT
Source
Solution
哦,这道题几乎涵盖了treap所有操作。然后窝写挂了好~~~长时间
话说BZOJ1500窝是不是AC无望QAQ
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }