洛谷P3369 【模板】普通平衡树(Treap/SBT)
P3369 【模板】普通平衡树(Treap/SBT)
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
-
插入x数
-
删除x数(若有多个相同的数,因只删除一个)
-
查询x数的排名(若有多个相同的数,因输出最小的排名)
-
查询排名为x的数
-
求x的前驱(前驱定义为小于x,且最大的数)
- 求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=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<=100000
2.每个数的数据范围:[-1e7,1e7]
来源:Tyvj1728 原名:普通平衡树
在此鸣谢
丁队模板,可靠
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 7 inline void read(int &x) 8 { 9 x = 0;char ch = getchar();char c =ch; 10 while(ch > '9' || ch < '0')c = ch, ch = getchar(); 11 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 12 if(c == '-')x = -x; 13 } 14 15 const int MAXN = 1000000 + 10; 16 17 int fa[MAXN], ch[MAXN][2], size[MAXN], cnt[MAXN],data[MAXN], root, nn, n, tot; 18 19 //左儿子返回0,否则返回1 20 int son(int x) 21 { 22 return x == ch[fa[x]][1]; 23 } 24 25 void pushup(int rt) 26 { 27 int l = ch[rt][0], r = ch[rt][1]; 28 size[rt] = size[l] + size[r] + cnt[rt]; 29 } 30 31 32 void rotate(int x) 33 { 34 int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b]; 35 if(z) ch[z][c] = x; else root = x; fa[x] = z; 36 if(a) fa[a] = y; ch[y][b] = a; 37 ch[x][!b] = y,fa[y] = x; 38 pushup(y),pushup(x); 39 } 40 41 void splay(int x, int i) 42 { 43 while(fa[x] != i) 44 { 45 int y = fa[x], z = fa[y]; 46 if(z == i) rotate(x); 47 else 48 if(son(x) == son(y))rotate(y), rotate(x); 49 else rotate(x), rotate(x); 50 } 51 } 52 53 void insert(int &rt, int x) 54 { 55 if(rt == 0) 56 { 57 rt = ++nn, data[nn] = x, size[nn] = cnt[nn] = 1; 58 return; 59 } 60 if(data[rt] == x) 61 { 62 ++cnt[rt], ++size[rt]; 63 return; 64 } 65 if(x < data[rt]) insert(ch[rt][0], x), fa[ch[rt][0]] = rt, pushup(rt); 66 else insert(ch[rt][1], x), fa[ch[rt][1]] = rt, pushup(rt); 67 } 68 69 int getpre(int rt, int x) 70 { 71 int p = rt,ans; 72 while(p) 73 { 74 if(x <= data[p]) p = ch[p][0]; 75 else ans = p, p = ch[p][1]; 76 } 77 return ans; 78 } 79 80 int getsuc(int rt, int x) 81 { 82 int p = rt,ans; 83 while(p) 84 { 85 if(x >= data[p]) p = ch[p][1]; 86 else ans = p, p = ch[p][0]; 87 } 88 return ans; 89 } 90 91 int getmn(int rt) 92 { 93 int p = rt, ans = -1; 94 while(p) 95 { 96 ans = p; 97 p = ch[p][0]; 98 } 99 return ans; 100 } 101 102 void del(int rt, int x) 103 { 104 if(data[rt] == x) 105 { 106 if(cnt[rt] > 1) --cnt[rt], --size[rt]; 107 else 108 { 109 splay(rt, 0); 110 int p = getmn(ch[rt][1]); 111 if(p != -1) 112 { 113 splay(p, rt); 114 root = p,fa[p] = 0,ch[p][0] = ch[rt][0],fa[ch[rt][0]] = p; 115 pushup(p); 116 } 117 else root = ch[rt][0], fa[ch[rt][0]] = 0; 118 } 119 return; 120 } 121 if(x < data[rt]) del(ch[rt][0], x); 122 else del(ch[rt][1], x); 123 pushup(rt); 124 } 125 126 int getk(int rt, int k) 127 { 128 if(data[rt] == k) 129 { 130 splay(rt, 0); 131 if(ch[rt][0] == 0) return 1; 132 else return size[ch[rt][0]] + 1; 133 } 134 if(k < data[rt])return getk(ch[rt][0], k); 135 else return getk(ch[rt][1], k); 136 } 137 138 int gettk(int rt, int k) 139 { 140 if(data[rt] == k) 141 { 142 splay(rt, 0); 143 if(ch[rt][0] == 0) return 1; 144 else return size[ch[rt][0]] + 1; 145 } 146 if(k < data[rt]) return gettk(ch[rt][0], k); 147 else return gettk(ch[rt][0], k); 148 } 149 150 int getkth(int rt, int k) 151 { 152 int l = ch[rt][0]; 153 if(size[l] + 1 <= k && k <= size[l] + cnt[rt]) return data[rt]; 154 if(size[l] + 1 > k)return getkth(ch[rt][0], k); 155 if(k > size[l] + cnt[rt]) return getkth(ch[rt][1], k - (size[l] + cnt[rt])); 156 } 157 158 int main() 159 { 160 read(n); 161 for(;n;--n) 162 { 163 int tmp1,tmp2; 164 read(tmp1);read(tmp2); 165 if(tmp1 == 1)++ tot,insert(root, tmp2); 166 else if(tmp1 == 2)-- tot, del(root, tmp2); 167 else if(tmp1 == 3)printf("%d\n", getk(root, tmp2)); 168 else if(tmp1 == 4)printf("%d\n", getkth(root, tmp2)); 169 else if(tmp1 == 5)printf("%d\n", data[getpre(root, tmp2)]); 170 else printf("%d\n", data[getsuc(root, tmp2)]); 171 } 172 return 0; 173 }