AcWing 算法提高课 可持久化

可持久化的前提:数据结构本身的拓扑结构不变

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个以上的数就去左边,否则去右边。

posted @ 2022-09-28 16:14  80k  阅读(98)  评论(0)    收藏  举报