可持久化数据结构学习笔记

史上最短学习笔记,没有之一。

可持久化线段树

相信大家都会。核心思想是每次修改最多改变 O(logn) 个元素,因此每次修改只需新建 O(logn) 个节点,时空复杂度均 nlogn

标记永久化

如果主席树需要支持区间操作,那么递归到整区间打标记时,就不能像普通线段树那样一路 pushdown 下去了,否则复杂度会退化。这时候我们就要用到标记永久化的思想,即在查询时额外记录一下目前从根节点到当前节点路径上所有节点的标记的和,传入参数中,这样递归左右儿子时再把对应的标记累加起来即可。这样复杂度不会退化,同时这种思路应用于普通的线段树上,常数也比带下推的线段树小不少。

可持久化并查集

本质上还是可持久化数组。

建两个可持久化数组(可持久化线段树),动态维护每一版本的 fadep 数组,每次合并就调用对应的 fadep 然后按秩合并即可。

由于每次操作最多涉及 O(logn) 个节点,所以总复杂度 nlog2n

可持久化 trie

本质上和可持久化线段树相同,还是每次插入一个节点就新建一个版本,时间复杂度 nlogv

稍微贴一个以前写的板子

可持久化平衡树

万物皆可可持久化(

wjz:什么都是可持久化数组(bushi

感觉其实套路也差不多吧,以 fhq-treap 为例,每次 split 时传入两个参数 a,b,假设我们要把节点 k 存在 a 一侧,那么传统的 fhq-treap 写法是直接将 a 赋为 k,但是对于可持久化 fhq-treap 而言,正确写法是令 a 为一个新建的节点,然后将 k 的信息传给 a 以后继续递归,merge 操作也是同样道理。

当然一般 treap 都是带修改的,这也就牵扯到标记的下方问题,标记永久化的套路当然也是适用的,一种不用标记永久化的思路是每次 pushdown 时都重新给左右儿子建一个备份,然后把标记传到这个备份上,并把左右儿子改成这个备份并清除当前节点的标记,正确性显然,只是常数稍微大些。

得出结论:可持久化系列都可以通过在板子基础上稍微改改得到(

板子 1 & 板子 2

总结

其实理论上来说所有非均摊数据结构都可以通过每次修改都新建一个节点的方式可持久化,然后节点个数上界就是不可持久化的版本总共遍历的节点个数,这一点都可以在板子的基础上,将“修改”改为“新建”得到。

可持久化并查集的维护方式稍微与众不同一些,不过既然并查集的本质也是数组,可持久化并查集也就可以通过类似于数组的方式维护。

posted @   tzc_wk  阅读(177)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示