参考:
前导:
如果你是初学者,你就只需要知道 pbds 比 FHQ Treap 码量小很多,
能起到一样的作用,好打好调,比 FHQ 稍微慢点,比赛还可以用。
怎么样?是不是动心了?
解析:
(1)编译环境
首先,我们需要添加此头文件:
#include<bits/extc++.h>
using namespace __gnu_pbds;
windos 环境添加之后会有编译错误,会跳转到这里:

不要怕,点这个:
![]()
然后到这里:

把 68 行的 ifdef 改成 ifndef,别忘了按 Ctrl s 保存!
就搞定啦,可以正常使用 pbds 了。
(2)了解 pbds tree
它封装了 hash、tree、trie、priority_queue 四种数据结构,我们先讲最常用的 tree。
定义格式:
tree<数据类型,无映射,排列方式,树的类型,更新方式> 变量名称;
数据类型:int、long long 等,一般使用 long long
无映射:使用 null_type
排列方式:less 从小到大 greater 从大到小,本题使用 less<long long>
树的类型:rd_tree、ov_tree、splay_tree,我下面有介绍,建议使用 rd_tree 即红黑树,因为它快
更新方式:除非你需要自写 update,否则使用 tree_order_statistics_node_update
关于一些平衡树知识拓展:
| 数据结构 | 适用场景 | 时间复杂度 | 小 tips |
| rd_tree 红黑树 | 通用(如 STL) | 均摊 | 常数较大,最坏情况查询比 AVL 慢 |
| ov_tree AVL 树 | 高频查询、 低频修改 | 删除插入慢 | |
| splay_tree 伸展树 | 频繁访问 同一节点 | 均摊 最坏 | 时间不可控 |
说回 pbds tree,它的可用操作:
treap.insert(x); //插入 x
treap.erase(x); //删除 x
treap.order_of_key(x); //返回 x的排名
treap.find_by_order(k); //返回第 k 小的值的迭代器
treap.lower_bound(x); //返回第一个大于等于 x 的元素的迭代器
treap.upper_bound(x); //返回第一个大于 x 的元素的迭代器
treap.join(b); //树的合并
treap.split(a, b); //树的分裂
(迭代器指针要想取得值,都要在前面加上 “ * ”)
然而还有个问题,红黑树会自动去重,所以我们把数据哈希。
先左移 20 位,再加上当前 for 的 i。
也有数据会特意卡哈希,改左移位数或者用读入时间都可以避免被卡。
(3)本题代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
typedef long long LL;
tree<LL, null_type, less<LL>, rb_tree_tag, tree_order_statistics_node_update> treap;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
int opt; LL x;
cin >> opt >> x;
if (opt == 1) {
treap.insert( (x << 20) + i );
}
else if (opt == 2) {
treap.erase(treap.lower_bound(x << 20));
}
else if (opt == 3) {
cout << ( treap.order_of_key(x << 20) + 1 ) << "\n";
}
else if (opt == 4) {
cout << ( (*treap.find_by_order(x - 1)) >> 20 ) << "\n";
}
else if (opt == 5) {
auto t = treap.lower_bound(x << 20);
t--;
cout << ( (*t) >> 20 ) << "\n";
}
else if (opt == 6) {
cout << ( (*treap.upper_bound( (x << 20) + n )) >> 20 ) << "\n";
}
}
return 0;
}
实测在洛谷上比 FHQ 慢 3/4 倍,校内 oj 慢 3 倍。
ps:pbds_tree 并不支持可持久化。


1895

被折叠的 条评论
为什么被折叠?



