__gnu_pbds::tree 用法简介

__gnu_pbds::tree 用法简介

概述

pbds即平板电视,里面实现了很多数据结构,NOI系列赛事可以使用,但很多 OJ 和网站无法使用。

其中有 __gnu_pbds::tree,是平衡树,支持查找位置、查找第 \(k\) 大、分裂、合并。功能远强与 std::set

性能

实现是红黑树,空间常数是 Treap 的 \(1.5\) 倍,时间常数是 Treap 的 \(1.1\)\(1.2\) 倍。

效率还可以,空间回收优秀,大部分平衡树题都可以用。

用法

库文件 & 命名空间

头文件

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

其中第一个头文件是使用 pbds 都要带的。

命名空间为 __gnu_pbds

注意你不应 using namespace __gnu_pbds,因为它和 std 都有 priority_queue,并且它还包含 tree trie 这样名字的数据结构。

定义

__gnu_pbds ::tree<Key, Mapped, Cmp_Fn = std::less<Key>, Tag = rb_tree_tag,
                  Node_Update = null_tree_node_update,
                  Allocator = std::allocator<char> >

Key存储的数据类型,注意不能存储多个值相同的元素,若需要可以用 pair 或封成 struct多存一个时间戳

Mapped 映射类型,如果无映射类似于 std::set,此处需填 __gnu_pbds::null_type,若有映射,如 std::map,应填映射类型,类似于 std::map<Key,Value>Value 类型。

Cmp_Fn 比较类型,默认从小到大,其用 std::less<Key>,从大到小可用 std::greater<Key>,若是自定义类型,这两者都需要重载小于号。

Tag 底层数据结构,默认为 rb_tree_tag,红黑树,速度最快。还可选 splay_tree_tagov_tree_tag 速度较慢别用。

Node_Update 更新节点的策略,可用于进阶操作,这里不提及。

Allocator 空间分配器类型,你不用管它。

  • 一般来说,你只需要用无映射基础版本即可,即 tree<Key,null_type>

迭代器

使用 iterator访问迭代器:

tree::iterator

同时它有 .begin().end(),用法和 std::set 类似。

成员函数

  • size() empty(),用法类似。

  • insert(x) 用法类似,插入元素,返回一个pairfirst是迭代器,second是一个 bool 表示是否插入成功

  • erase(x),用法类似,删除值为 x 的元素或删除迭代器为 x 的元素,删除迭代器后迭代器失效。函数返回一个 bool 表示是否成功。

  • lower_bound(x) upper_bound(x),用法类似,第一个大于等于和第一个大于,返回迭代器。

  • order_of_key(x) 返回值为 \(x\) 的排名,按定义的比较方式比较。

  • find_by_order(x) 返回按比较方式比较的\(x\)的迭代器。

  • x.join(y) \(y\) 树并入 \(x\)\(y\) 被删除。前提是两棵树值域互不相交

  • x.split(k,y)分裂,值小于等于 \(k\) 的属于 \(x\) 树,剩下的属于 \(y\) 树。

以上函数的时间复杂度均为 \(O(\log n)\)

posted @ 2024-08-19 21:32  dengchengyu  阅读(87)  评论(0编辑  收藏  举报