可持久化的前提:数据结构本身的拓扑结构不变
trie、线段树、树状数组、堆等都可持久化
平衡树(一般)需要左旋和右旋,不可持久化
可持久化希望将数据结构的全部修改记录下来(历史版本)
核心思想:只记录每一个版本与前一个版本不一样的地方
1、可持久化Trie
可以发现,绿线表示同一个点,但是下方的子树有修改(需要裂开),跨版本的蓝线,可以连到没有修改的子树。
每一个版本,只对比和上一个版本不一样的地方
算法流程
开辟一个新的根,然后向下遍历时,如果上一个版本已经存在则复制(连出全部跨版本的蓝线)。
tr[q][si]相当于有变化的位置裂开一个新的节点(绿线对应的右侧位置),或者新开辟一个节点 。
例题:https://www.acwing.com/problem/content/258/
可持久化trie维护数字的前缀异或和
2、可持久化线段树(主席树)
不能用堆的方式存,要用指针的方式存
注意:可持久化线段树(一般)难以处理懒标记,故难以进行区间修改操作
可持久化线段树由于不用新添加点,(每一个节点在上一个版本已经存在了),比trie好写?
例题:区间第k小数
求数组下标区间内的第k小数
https://www.acwing.com/problem/content/description/257/
线段树表示数值区间中存在的数的个数。
每个版本表示插入第i个数字后的线段树。
然后在线段树上二分,如果在左边可以查到k个以上的数就去左边,否则去右边。
标签:持久,trie,线段,一个,算法,版本,节点,AcWing From: https://www.cnblogs.com/ydUESTC/p/16738494.html