P3369 【模板】普通平衡树
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
-
插入x数
-
删除x数(若有多个相同的数,因只删除一个)
-
查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
-
查询排名为x的数
-
求x的前驱(前驱定义为小于x,且最大的数)
- 求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1 \leq opt \leq 61≤opt≤6 )
输出格式:
对于操作3,4,5,6每行输出一个数,表示对应答案
输入输出样例
输入样例#1: 复制
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598
输出样例#1: 复制
106465 84185 492737
说明
时空限制:1000ms,128M
1.n的数据范围: n \leq 100000n≤100000
2.每个数的数据范围: [-{10}^7, {10}^7][−107,107]
来源:Tyvj1728 原名:普通平衡树
在此鸣谢
我是用来练习 可持久化Treap的。。
1 #include <ctime> 2 #include <cstdio> 3 #include <cctype> 4 #include <cstdlib> 5 6 const int MAXN = 500010; 7 8 int n, id; 9 10 int tree[MAXN][2], pri[MAXN], val[MAXN], siz[MAXN]; 11 12 inline void read(int&x) { 13 int f = 1; register char c = getchar(); 14 for(x = 0; !isdigit(c); c == '-'&& (f = -1), c=getchar()); 15 for(; isdigit(c); x = x * 10 + c - 48, c = getchar()); 16 x = x * f; 17 } 18 19 namespace Treap { 20 21 int New(int v) { 22 siz[++id] = 1; 23 val[id] = v; 24 pri[id] = rand(); 25 return id; 26 } 27 28 void split(int now, int v, int&x, int&y) { 29 if(!now) { 30 x = y = 0; 31 return; 32 } 33 if(val[now] <= v) x = now, split(tree[now][1], v, tree[now][1], y); 34 else y = now, split(tree[now][0], v, x, tree[now][0]); 35 siz[now] = siz[tree[now][1]] + siz[tree[now][0]] + 1; 36 } 37 38 int merge(int x,int y) { 39 if(!x || !y) return x + y; 40 if(pri[x] < pri[y]) { 41 tree[x][1] = merge(tree[x][1], y); 42 siz[x] = siz[tree[x][1]] + siz[tree[x][0]] + 1; 43 return x; 44 } 45 else { 46 tree[y][0] = merge(x, tree[y][0]); 47 siz[y] = siz[tree[y][1]] + siz[tree[y][0]] + 1; 48 return y; 49 } 50 } 51 52 int kth(int now, int k) { 53 while(1) { 54 if(k <= siz[tree[now][0]]) now = tree[now][0]; 55 else if(k == siz[tree[now][0]] + 1) return now; 56 else k -= siz[tree[now][0]] + 1, now = tree[now][1]; 57 } 58 } 59 } 60 61 int main(int argc,char**argv) { 62 read(n); 63 srand((unsigned)time(NULL)); 64 int flag, v, root = 0, x, y, z; 65 for(int i = 1; i <= n; ++i) { 66 read(flag);read(v); 67 if(flag == 1) { 68 Treap::split(root, v, x, y); 69 root = Treap::merge(Treap::merge(x, Treap::New(v)), y); 70 } 71 else if(flag == 2) { 72 Treap::split(root, v, x, z); 73 Treap::split(x, v - 1, x, y); 74 y = Treap::merge(tree[y][0], tree[y][1]); 75 root = Treap::merge(Treap::merge(x, y), z); 76 } 77 else if(flag == 3) { 78 Treap::split(root, v - 1, x, y); 79 printf("%d\n",siz[x] + 1); 80 root = Treap::merge(x, y); 81 } 82 else if(flag == 4) printf("%d\n", val[Treap::kth(root, v)]); 83 else if(flag == 5) { 84 Treap::split(root, v - 1, x, y); 85 printf("%d\n",val[Treap::kth(x, siz[x])]); 86 root = Treap::merge(x, y); 87 } 88 else { 89 Treap::split(root, v, x, y); 90 printf("%d\n",val[Treap::kth(y, 1)]); 91 root = Treap::merge(x, y); 92 } 93 } 94 return 0; 95 }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现