3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9629 Solved: 4091
[Submit][Status][Discuss]
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
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2
Source
FHQ Treap
1 #include <bits/stdc++.h> 2 3 const int N = 500005; 4 5 int ls[N], rs[N], vl[N], tg[N], sz[N]; 6 7 inline int node(int v) 8 { 9 static int t = 1; 10 sz[t] = 1; 11 vl[t] = v; 12 tg[t] = rand(); 13 return t++; 14 } 15 16 int merge(int a, int b) 17 { 18 if (!a || !b)return a + b; 19 if (tg[a] > tg[b]) 20 { 21 rs[a] = merge(rs[a], b); 22 sz[a] = 1 + sz[ls[a]] + sz[rs[a]]; 23 return a; 24 } 25 else 26 { 27 ls[b] = merge(a, ls[b]); 28 sz[b] = 1 + sz[ls[b]] + sz[rs[b]]; 29 return b; 30 } 31 } 32 33 void split(int t, int k, int &a, int &b) 34 { 35 if (!t)a = b = 0; 36 else 37 { 38 if (vl[t] <= k) 39 a = t, split(rs[t], k, rs[t], b); 40 else 41 b = t, split(ls[t], k, a, ls[t]); 42 sz[t] = 1 + sz[ls[t]] + sz[rs[t]]; 43 } 44 } 45 46 int kth(int t, int k) 47 { 48 if (k <= sz[ls[t]]) 49 return kth(ls[t], k); 50 else if (k == sz[ls[t]] + 1) 51 return t; 52 else 53 return kth(rs[t], k - sz[ls[t]] - 1); 54 } 55 56 signed main(void) 57 { 58 srand(5264); 59 60 int n, r = 0; scanf("%d", &n); 61 62 for (int a, b, x, y, z; n--; ) 63 { 64 scanf("%d%d", &a, &b); 65 66 if (a == 1) 67 { 68 split(r, b, x, y); 69 r = merge(x, node(b)); 70 r = merge(r, y); 71 } 72 else if (a == 2) 73 { 74 split(r, b, x, z); 75 split(x, b - 1, x, y); 76 y = merge(ls[y], rs[y]); 77 r = merge(x, y); 78 r = merge(r, z); 79 } 80 else if (a == 3) 81 { 82 split(r, b - 1, x, y); 83 printf("%d ", sz[x] + 1); 84 r = merge(x, y); 85 } 86 else if (a == 4) 87 printf("%d ", vl[kth(r, b)]); 88 else if (a == 5) 89 { 90 split(r, b - 1, x, y); 91 printf("%d ", vl[kth(x, sz[x])]); 92 r = merge(x, y); 93 } 94 else 95 { 96 split(r, b, x, y); 97 printf("%d ", vl[kth(y, 1)]); 98 r = merge(x, y); 99 } 100 } 101 }
1 #include <bits/stdc++.h> 2 const int N = 500005; 3 int ls[N], rs[N], vl[N], tg[N], sz[N], tot = 1; 4 int node(int v) { 5 return vl[tot] = v, sz[tot] = 1, tg[tot] = rand(), tot++; 6 } 7 int merge(int a, int b) { 8 if (!a || !b)return a + b; 9 if (tg[a] > tg[b]) { 10 rs[a] = merge(rs[a], b); 11 sz[a] = 1 + sz[ls[a]] + sz[rs[a]]; 12 return a; 13 } 14 else { 15 ls[b] = merge(a, ls[b]); 16 sz[b] = 1 + sz[ls[b]] + sz[rs[b]]; 17 return b; 18 } 19 } 20 int split(int t, int k, int &a, int &b) { 21 if (!t)return a = b = 0, 0; 22 if (vl[t] <= k) 23 a = t, split(rs[t], k, rs[t], b); 24 else 25 b = t, split(ls[t], k, a, ls[t]); 26 return sz[t] = 1 + sz[ls[t]] + sz[rs[t]]; 27 } 28 int kth(int t, int k) { 29 return k <= sz[ls[t]] ? kth(ls[t], k) : ((k -= sz[ls[t]] + 1) ? kth(rs[t], k) : vl[t]); 30 } 31 signed main(void) { 32 int n, r = 0, a, b, x, y, z; 33 for (scanf("%d", &n); n--; ) { 34 scanf("%d%d", &a, &b); 35 if (a == 1) 36 split(r, b, x, y), r = merge(merge(x, node(b)), y); 37 else if (a == 2) 38 split(r, b, x, z), split(x, b - 1, x, y), r = merge(merge(x, merge(ls[y], rs[y])), z); 39 else if (a == 3) 40 split(r, b - 1, x, y), printf("%d ", sz[x] + 1), r = merge(x, y); 41 else if (a == 4) 42 printf("%d ", kth(r, b)); 43 else if (a == 5) 44 split(r, b - 1, x, y), printf("%d ", kth(x, sz[x])), r = merge(x, y); 45 else 46 split(r, b, x, y), printf("%d ", kth(y, 1)), r = merge(x, y); 47 } 48 }
@Author: YouSiki