ext 库及 pb_ds 在 OI 中的应用
ext 库在 OI 中的应用
写一个帖子,防止以后忘了。
pb_ds 部分
pb_ds 万能头
#include<bits/extc++.h>
来包含 ext 库中所有的头文件(例如 pb_ds 和 rope)。
但是这句话在非 Ubuntu 环境下可能会显示缺失 iconv.h
。 这个在 OI 是可以使用的,因为评测机的 NOI-linux2.0 是 Ubuntu 环境,但如果你考试不开虚拟机是不可以在 Windows 下运行的。
优先队列
由于常数的优劣性,本文只介绍 pairing_heap_tag
配对堆。
Ps:modify
相当于更改一个点的点权,erase
相当于删除一个点,join
相当于合并两个堆,并清空后者,基本替代左偏树。
然而定义却比较复杂。
示例定义:
#include<bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
__gnu_pbds::priority_queue<int,greater<int>> a,c;//定义类型
__gnu_pbds::priority_queue<int> d;//默认大根堆
__gnu_pbds::priority_queue<int>::point_iterator it;//定义指针
struct node
{
int x,y;
bool friend operator <(const node a,const node b)
{
return a.x+a.y<b.x+b.y;
}
};
__gnu_pbds::priority_queue<node> b;
int main()
{
a.push(1),a.push(2),a.push(3);
cout<<a.top()<<"\n";//输出 1
c.join(a);
cout<<a.size()<<"\n";//输出 0
cout<<c.size()<<"\n";//输出 3
cout<<c.top()<<"\n";//输出 1
c.pop();
cout<<c.top()<<"\n";//输出 2
d.push(1),it=d.push(2),d.push(3);
cout<<d.top()<<"\n";//输出 3
d.modify(it,10);
cout<<d.top()<<"\n";//输出 10
b.push({1,1}),b.push({2,2}),b.push({3,3});
cout<<b.top().x<<"\n";//输出 3
}
建议阅读:堆 - OI Wiki
平衡树
#include <ext/pb_ds/assoc_container.hpp>//因为tree定义在这里 所以需要包含这个头文件
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
Key
: 键的类型,示例的类型是int
。Mapped
: 映射规则(Mapped-Policy)类型:- 如果要指示关联容器是 集合,类似于存储元素在
std::set
中,此处填入null_type
,低版本g++
此处为null_mapped_type
; - 如果要指示关联容器是 带值的集合,类似于存储元素在
std::map
中,此处填入类似于std::map<Key, Value>
的Value
类型。
- 如果要指示关联容器是 集合,类似于存储元素在
Cmp_Fn
: 关键字比较函数,例如std::less<Key>
。Tag
: 选择使用何种底层数据结构类型,默认是rb_tree_tag
,由于其他两种效率不高,所以这里只解释此类型。Node_Update
:用于更新节点的策略,默认使用null_node_update
,若要使用kth
和rank
的函数,需要使用tree_order_statistics_node_update
。
成员函数
insert(x)
:向树中插入一个元素 x,返回std::pair<point_iterator, bool>
。erase(x)
:从树中删除一个元素/迭代器 x,返回一个bool
表明是否删除成功。order_of_key(x)
:返回 x 以Cmp_Fn
比较的较小数的个数(求完以后加 1,才是排名)。find_by_order(x)
:返回Cmp_Fn
比较的排名所对应元素的迭代器。lower_bound(x)
:以Cmp_Fn
比较做lower_bound
,返回迭代器。upper_bound(x)
:以Cmp_Fn
比较做upper_bound
,返回迭代器。join(x)
:将 x 树并入当前树,前提是两棵树的类型一样,x 树被删除。split(x,b)
:以Cmp_Fn
比较,小于等于 x 的属于当前树,其余的属于 b 树。empty()
:返回是否为空。size()
:返回大小。
注意事项
- 使用
null_type
的平衡树是不支持重复元素的,如有重复元素插入需要,可以开pair
第二位搭配随机数食用。
失效保证(invalidation_guarantee)
pb_ds 提供了三种失效保证(不是所有的容器的有三种),分别是:
basic_invalidation_guarantee
- 基本失效保证,最弱的无效保证。可以保证在容器没有修改时候迭代器,指针等保持有效。
Ps:没有修改的情况下,指针所指的元素还是原来的元素。
point_invalidation_guarantee
- 点失效保证,更强的无效保证。可以保证在修改容器但迭代器等所指的东西没有被删除是保持有效。
Ps:修改后,如果修改的不是指针所指的元素,那么指针所指的元素还是原来的元素。
range_invalidation_guarantee
- 范围失效保证,最强的无效保证。在 点失效保证 的基础上,保证相对位置不变。
Ps:修改后,如果修改的不是指针所指的元素,那么指针所指的元素还是原来的元素;同时,保证指针的相对位置不变。
pairing_heap_tag
均为点失效保证。
rb_tree_tag
为范围失效保证。
其它
ROPE
参考文献
鸽一下……
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现