BZOJ 3224: Tyvj 1728 普通平衡树
2017-04-15 18:57
363 查看
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
101 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
10646584185
492737
HINT
1.n的数据范围:n<=1000002.每个数的数据范围:[-2e9,2e9]
分析
就是学splay模板而已,但我感觉常数好大,之后慢慢改改代码
#include <bits/stdc++.h> #define N 500000 struct { int fa; int son[3]; int size[3]; int count; int cover; }t ; int n; int node; int root; void rotate(int x,int w) { int f = t[x].fa; int g = t[f].fa; t[f].son[3 - w] = t[x].son[w]; if (t[x].son[w]) t[t[x].son[w]].fa = f; t[x].fa = g; t[f].size[3 - w] = t[x].size[w]; t[x].size[w] += t[f].size[w] + 1; if (g) { if (f == t[g].son[1]) t[g].son[1] = x; else t[g].son[2] = x; } t[f].fa = x; t[x].son[w] = f; } void splay(int x) { int y; while (t[x].fa) { y = t[x].fa; if (!t[y].fa) { if (x == t[y].son[1]) rotate(x,2); else rotate(x,1); continue; } if (y == t[t[y].fa].son[1]) { if (x == t[y].son[1]) rotate(y,2), rotate(x,2); else rotate(x,1), rotate(x,2); } else { if (x == t[y].son[2]) rotate(y,1), rotate(x,1); else rotate(x,2), rotate(x,1); } } root = x; } void insert(int x,int add) { if (t[x].cover >= add) { if (!t[x].son[1]) { t[x].son[1] = ++node; t[node].cover = add; t[node].fa = x; if (!root) root = node; } else insert(t[x].son[1],add); t[x].size[1]++; } else { if (!t[x].son[2]) { t[x].son[2] = ++node; t[node].cover = add; t[node].fa = x; if (!root) root = node; } else insert(t[x].son[2],add); t[x].size[2]++; } } void del(int x,int dec) { if (!x) return; if (dec == t[x].cover) { splay(x); if (!t[x].son[1] && !t[x].son[2]) { root = 0; return; } if (!t[x].son[1]) { root = t[x].son[2]; t[t[x].son[2]].fa = 0; return; } if (!t[x].son[2]) { root = t[x].son[1]; t[t[x].son[1]].fa = 0; return; } int f = t[x].son[1]; int tmp = t[x].son[2]; while (t[f].son[2]) f = t[f].son[2]; splay(f); t[f].son[2] = tmp; t[tmp].fa = f; return; } if (dec < t[x].cover) del(t[x].son[1],dec); else del(t[x].son[2],dec); } int kth(int x,int add,int now) { insert(root,add); splay(node); int ans = t[node].size[1] + 1; del(node,add); return ans; } int findK(int x,int k) { if (k == t[x].size[1] + 1) return t[x].cover; if (k <= t[x].size[1]) return findK(t[x].son[1],k); else return findK(t[x].son[2],k - t[x].size[1] - 1); } bool flag; int pred(int x,int k) { int f = t[x].son[1]; if (!f) return 0; while (t[f].son[2]) f = t[f].son[2]; if (t[f].cover != k) flag = 1; return f; } int succ(int x,int k) { int f = t[x].son[2]; if (!f) return 0; while (t[f].son[1]) f = t[f].son[1]; if (t[f].cover != k) flag = 1; return f; } int main() { int n; scanf("%d",&n); for (int i = 1; i <= n; i++) { int opt,x; scanf("%d%d",&opt,&x); if (opt == 1) insert(root,x), splay(node); if (opt == 2) del(root,x); if (opt == 3) printf("%d\n",kth(root,x,0)); if (opt == 4) printf("%d\n",findK(root,x)); if (opt == 5) { int ans; insert(root,x); splay(node); for (flag = 0, ans = pred(root,x); !flag || !ans; splay(ans), ans = pred(root,x)); del(root,x); printf("%d\n",t[ans].cover); } if (opt == 6) { int ans; insert(root,x); splay(node); for (flag = 0, ans = succ(root,x); !flag || !ans; splay(ans), ans = succ(root,x)); del(root,x); printf("%d\n",t[ans].cover); } } }
相关文章推荐
- bzoj 3224 Tyvj 1728 普通平衡树 (替罪羊树模板)
- 【BZOJ3224】 Tyvj 1728 普通平衡树
- [BZOJ 3224] [Tyvj 1728] 普通平衡树
- 【bzoj3224】 Tyvj1728—普通平衡树
- (vector通过)bzoj3224: Tyvj 1728 普通平衡树
- BZOJ 3224 Tyvj 1728 普通平衡树——treap
- bzoj3224 Tyvj 1728 普通平衡树
- 【BZOJ】3224: Tyvj 1728 普通平衡树
- bzoj 3224: Tyvj 1728 普通平衡树
- bzoj3224: Tyvj 1728 普通平衡树
- [置顶] BZOJ 3224 Tyvj 1728 普通平衡树(替罪羊树)
- bzoj 3224: Tyvj 1728 普通平衡树
- BZOJ 3224: Tyvj 1728 普通平衡树
- [bzoj3224]Tyvj 1728 普通平衡树
- bzoj3224 Tyvj1728 普通平衡树
- [BZOJ3224]Tyvj 1728 普通平衡树
- bzoj 3224/Tyvj 1728 普通平衡树
- [Bzoj3224]Tyvj 1728 普通平衡树
- _bzoj3224 Tyvj 1728 普通平衡树【Splay】
- BZOJ 3224: Tyvj 1728 普通平衡树 pb_ds