#pHSybttg040604. 1568:普通平衡树
1568:普通平衡树
题目描述
这是一道模板题。
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
- 插入 数;
- 删除 数(若有多个相同的数,只删除一个);
- 查询 数的排名(若有多个相同的数,输出最小的排名);
- 查询排名为 的数;
- 求 的前驱(前驱定义为小于 ,且最大的数);
- 求 的后继(后继定义为大于 ,且最小的数)。
输入格式
第一行为 ,表示操作的个数。
下面 行每行有两个数 和 , 表示操作的序号()。
输出格式
对于操作 每行输出一个数,表示对应答案。
样例
输入样例 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
样例解释
操作序列:
1 106465:插入 106465。4 1:查询排名为 1 的数(最小数),当前只有 106465,输出 106465。1 317721:插入 317721。1 460929:插入 460929。1 644985:插入 644985。1 84185:插入 84185。1 89851:插入 89851。6 81968:查询 81968 的后继(大于 81968 的最小数)。当前集合排序:84185,89851,106465,317721,460929,644985。81968 的后继是 84185,输出 84185。1 492737:插入 492737。5 493598:查询 493598 的前驱(小于 493598 的最大数)。当前集合排序:84185,89851,106465,317721,460929,492737,644985。小于 493598 的最大数是 492737,输出 492737。
数据范围
时间限制:1000 ms
内存限制:262144 KB
提示
本题为平衡树的模板题。可以使用多种平衡树实现,如:Treap(树堆)、Splay(伸展树)、AVL、红黑树等,也可以使用权值线段树或树状数组(需要离线离散化)。
常见实现方式:
- Treap:每个节点有随机优先级,通过旋转维护堆性质,实现简单。
- Splay:通过伸展操作将节点提到根,便于操作。
- 无旋 Treap(FHQ Treap):通过分裂合并实现,代码简洁。
- 替罪羊树:通过重构维持平衡。
操作解释:
- 插入:按 BST 性质插入后调整平衡。
- 删除:找到节点,若为叶子直接删,否则用前驱或后继替换后删除。
- 查询排名:返回比 小的数的个数 +1。
- 查询第 k 小:根据子树大小在 BST 中查找。
- 前驱:比 小的最大数。
- 后继:比 大的最小数。
注意:
- 可能有重复数字,处理重复时可以:
- 每个节点维护一个计数
cnt表示相同数字个数。 - 或者允许 BST 中存在相同键值,但需要正确处理排名(多个相同数取最小排名)。
- 每个节点维护一个计数
- 对于负数,平衡树应能正确处理比较。
推荐实现: FHQ Treap(无旋 Treap),代码较短且易于理解。