pb_ds 速通

news/2024/12/16 23:16:10/文章来源:https://www.cnblogs.com/xsyc/p/18611299

Intro

深度好文

成文过程中参考了大量资料,这里一并谢过。

我在 2024.11.22 调试 LG P2596 到凌晨 00:32:21 破防所以加快学习了 pb_ds

pb_ds: Policy-Based Data Structures。封装了很多有用的数据结构,常用的有:

  • Hash
  • 平衡树
  • 字典树
  • 可持久化平衡树

但是严格上讲 pb_ds 并不属于 STL,只在使用 libstdc++ 为标准库的编译器下可以使用,主要内容位于 namespace __gnu_pbds 中,经 CCF 声明,在 NOI 系列比赛中可以使用(天天用 __lg__gcd 了还怕这个?)

一般而言,pb_ds 常数较大。

使用 pb_ds 需要:

#include <ext/pb_ds/assoc_container.hpp> // 必须引用,理解为底层定义
#include <ext/pb_ds/tree_policy.hpp> // tree
#include <ext/pb_ds/hash_policy.hpp> // hash
#include <ext/pb_ds/trie_policy.hpp> // trie
#include <ext/pb_ds/priority_queue.hpp> // priority_queue

有万能头,但是 Win 无法过编:

#include <bits/extc++.h>

hash & trie

pb_ds 中有两个 Hash:

cc_hash_table<Key, Value>;
gp_hash_table<Key, Value>;

第一个使用了拉链法第二个则是探测法,但是注意到我们有更稳定好用的 std::map 和手动重载后的 std::unordered_map,故在此不做赘述。

trie 类用的也比较少,毕竟手写 Trie 并不困难,而且 Trie 实在是太重要了,包括延伸出的 01-Trie……可以看源文件了解一下成员函数。

__gnu_pbds::trie<string, null_type,trie_string_access_traits<>,pat_trie_tag,trie_prefix_search_node_update> tr;/* 常用的操作 */
tr.insert(str);
tr.erase(str);
tr.join(another_trie);// 遍历某一个前缀的所有字符串
std::pair<Trie::iterator, Trie::iterator> range = tr.prefix_range(prefix);
for (auto it = range.first; it != range.second; ++it) {cout << *it << endl;
}

priority_queue

Why not try OI-Wiki? and official docs?

学习一下仿函数便于重定义堆的排序,本质上为重载括号运算符,在 Template 中比较常用,使用方法如:

template <typename T>
struct comp {bool operator() (const T &x, const T &y) {return dis[x] > dis[y];}
};std::priority_queue<int, std::vector<int>, comp> q;

这样我们的 std::priority_queue 就是存储下标,按照 \(dis_i\) 来排序的小根堆。

定义如:

__gnu_pbds::priority_queue<T, Compare, Tag, Allocator>

第四个在 OI 中基本不会用到,Tag 的另外几种可以看 OI-Wiki,但是基本上我们只在自定义非原生元素时使用 pb_ds 的堆,而其中 pairing_heap_tag 的表现是最佳的。

这是一些常用的成员函数:

  • push()(会返回元素位置迭代器)
  • pop()
  • top()
  • size()
  • empty()
  • modify(point_iterator, const key) 重要好用,均摊是 \(\log n\)
  • erase(point_iterator)
  • join(__gnu_pbds::priority_queue &x) 重要好用,合并到当前堆的同时清空 \(x\)

tree

Why not try OI-Wiki? and official docs?

定义如:

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

其中注意到:

  • Mapped 表示映射规则,一般而言我们使用 null_type 表示无映射(类似于丢进 std::set 里);若关联到带值的集合(类似于丢到 std::map 里),则填入类似 std::map<Key, Value> 中的 Value 类型。
  • Tag 表示底层平衡树类型,一般而言我们使用 rb_tree_tag,这是一种跑得飞快但是极为难调难写的平衡树
  • Node_Update 一般使用 tree_order_statistics_node_update,因为我们需要使用 order_of_keyfind_by_order

这是一些常用的成员函数(基于 Cmp_Fn 比较):

  • insert(x) 返回 std::pair<point_iterator, bool>
  • erase(x) 删除一个元素或迭代器
    • \(x\) 为迭代器:返回下一个迭代器,若为末尾则返回 end()
    • \(x\) 为元素:返回是否删除成功(不存在就删除失败咯)
  • order_of_key(x):返回从 \(0\) 开始的排名
  • find_by_order(x) 返回对于排名所对于元素的迭代器
  • lower_bound(x) 前驱
  • upper_bound(x) 后继
  • join(x)比较函数和元素类型 相同的情况下合并两棵 tree 到当前树,清空 \(x\)
  • split(x, b) 小于等于 \(x\) 的属于当前树,其余的属于 \(b\)
  • empty()
  • size()

!!!join(x) 函数需要保证两棵树的值域 不相交(也就是并入树内所有值必须全部 \(\gt / \lt\) 当前树内的所有值),否则会 throwjoin_error

如果要合并两棵树且有交集,则需要将一棵树的元素一一插入到另一棵树中

rope

用于实现可持久化数组、可持久化平衡树。

如前文所述,严格来说,pb_ds 不属于 STL,然而 rope 不属于 pb_ds,头文件位于 rope,在命名空间 __gnu_cxx 中。

__gnu_cxx::rope 支持:

  • at(x) / operator[]\(O(1)\)
  • push_back() / append\(O(\log n)\)
  • insert(x, other)x 的位置插入另一个串:\(T_{\min} O(\log n) / T_{\max} O(n)\)
  • erase(x, len) 删除 x 位置开始的 len 个元素:\(O(\log n)\)
  • replace(x, len, other)x 位置开始的 len 个位置替换为 otherlen 可省略:\(O(\log n)\)
  • substr(x, len)x 开始 len 位截取:\(O(\log n)\)
  • operator + 联结两个 rope

黑科技:支持 \(O(1)\) 复制,还不炸空间:

constexpr int N = 1e5 + 7;rope<int> *his[N];
his[i] = new rope<int> (*his[i - 1]);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854032.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

11CSS属性-颜色表示-chrome调试-浏览器渲染

一、今日内容 首先对这些属性进行一个演练 想要深刻理解所有常用的CSS属性,最好先学会以下几个最基础最常用的CSS属性font-size 文字大小 color前景色(文字颜色) background-color背景色 width宽度 height高度二、对CSS常用属性进行演练 1、字体的默认大小是16px的还可以看到…

使用win10 wsl子系统将 rust 程序静态编译为linux可执行文件

chapter Ⅰ 事情起因 最近在学习rust, 想把一部分java服务迁移至rust编写,但由于公司服务器都是linux系统,所以在找windows下交叉编译为linux可执行文件的方法,把bing首页搜索的结果试了个遍都不行, 始终报错“musl-gcc”无法找到,搜遍全网都无法解决。 最终在我不断尝试的…

Spring Cloud 负载均衡配置 (@LoadBalanced)

一、负载均衡 目前是两种 Ribbon 和 spring-cloud-loadbalancer - Ribbon已经闭源 配置策略较多 :轮询,随机,权重,自定义 四种负载均衡方案 配置方式yml 注解- spring-cloud-loadbalancer属于springcloud,项目兼容性更好 配置策略: 更注重 自定义(默认为轮询) 配置方式注…

架构信息收集

引子:一个Web应用的构成,由诸多组件&服务相结合,而域名仅是处于Web架构中最表层的一部分。本篇则由表及里,依次对整个Web应用架构,所需收集的信息类型、收集方式等进行介绍。附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正! 2.2 架构…

x86指令集 字节大小

x86指令集 字节大小 https://bbs.kanxue.com/thread-190127.htm 最近对x86_32架构下的许多程序进行了指令长度统计,结果表明所有程序所涉及的指令长度范围均为:1~11字节。而根据INTEL 开发者手册上介绍的指令的最大长度限制为15字节。但是,在什么情况或者架构上才会有12~15字…

实际项目中不一样的《桥接模式》

图片缩略图功能 需要对图片生产缩略图,压缩并保存到不同的介质中。输入端可能是本地图片,也可能是网络图片。保存的位置可能是本地,也有可能是第三方的minio、阿里云oss、七牛云oss。并且这些途径可能随时扩展。为了设计的灵活性,这里就要把输入可输出抽象出来,应用层通过…

一款渗透测试信息收集集成工具--mitan密探

本工具仅供安全测试人员运用于授权测试, 禁止用于未授权测试, 违者责任自负。作者及本公众号相关负责人不对您使用该工具所产生的任何后果负任何法律责任,在扫描模块使用多线程,在测试过程中根据目标的实际情况进行调整,切勿进行大线程低延时的大规模快速扫描,以免对目标服务…

最大网络流基本概念

1. 基本概念 1.1 流网络,不考虑反向边如果存在反向边也没事,不如有u->v和v->u两条边,那么就可以新加入一个点 p,u->v,v->p,p->u,转化为这三条边 1.2 可行流,不考虑反向边 1.2.1 两个条件:容量限制、流量守恒 容量限制:每条边流的不能超过这条边的权值 流量守…

sqli-labs

sqli-labs Less-1 基于错误的GET单引号字符型注入 index.php分析error_reporting(0); 不反馈错误 isset($_GET[id]) 检查($ _GET[id])参数是否设置 LIMIT 0,1 从第一条开始记录,只取一条记录1.推测闭合方式?id=1\输入\ ,后面是 ,推测是单引号闭合 输入 ?id=1 报错 输入 ?…

一文读懂:AI创业和投融资领域常见专有名词缩写详解

=== 预计悦读时间:3分钟 | 📚字数:约1000字——知识满满,不虚此行!🤔为什么你需要这篇神器? 就像由算法推荐给各位好奇的同学一样,我也被这些术语所困扰,想象一下,你正沉浸在一场关于AI的精彩演讲或者播客中,突然,一个神秘的英文缩写从嘉宾口中飞出,像是外星语言般让你瞬…

Simplex Method (单纯形方法)

学习目标:在本节中,我们将学习使用\(\textbf{单纯形法}\)解决线性规划最大化问题:(In this section, we will learn to solve linear programming maximization problems using the Simplex Method:)识别并建立标准的最大化形式的线性规划 (Identify and set up a linear pr…

《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解

《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解@目录二、高级篇(大厂进阶)4.Docker网络4.1Docker网络是什么4.2常用基本命令4.3能干嘛4.4网络模式4.4.1总体介绍4.4.2容器实例内默认网络IP生产规则4.4.3案例说明…