一个不套路的东西,没啥好说的。
感觉不能叫学习笔记吧,只能叫「学会了祭」(
UPD 2020.8.27:算了还是写点字吧(
标记永久化是跟懒标记相对的一种树形数据结构区间修改维护方式。
不难发现,用懒标记维护的话,任意时刻访问任意节点,它维护的信息一定是最新版(即算上了目前所有有关它的贡献)。这样懒癌患者会很舒服,直接调用节点信息就是真实值了,不用有其他顾虑。
标记永久化同样是每个节点维护一个信息和标记。不同的是,这里的信息是在初始值的基础上,只算上落在子树内节点(即后代)的贡献,而标记是专门记录落在此节点上的贡献和的。
区间修改的时候:对于每个经过的节点,显然它一定是将来要将待修改区间分成的节点(即被待修改区间完全包含)的祖先,也就是分成的节点在它子树内,于是直接更新它的信息(上传或直接修改,具体看复杂度和可实现性);对于每个要将待修改区间分成的节点,它也是经过的节点所以信息也按上面改,而且它的标记也要把本次的贡献算上。
显然,对一个节点有贡献的节点只可能是它的祖先或后代。后代的贡献已经算在它自身维护的信息中了,若想获得此节点的真实信息,要需要算上它的祖先贡献和。而当前节点祖先和恰好是可以一路一边走下来一边计算的。仔细想想这个就是树上差分的思想。
不难发现,标记永久化对树的形态的稳定性有较强的依赖性。线段树和 Trie 显然都是可以标记永久化的;而大部分平衡树的形态都极其不稳定,一些祖先改啊改,标记永久化就失效了,这时候只能用懒标记及时地把祖先的贡献算到当前节点维护的信息里。
一些应用:
- 主席树。由于一个节点可能有多个(属于不同历史版本的)爸爸,懒标记的话就会把这些爸爸的贡献都算上
,也就是实现了时代的融合,肯定是不行的。标记永久化恰好可以解决这个问题,对于每个历史版本,从根一路走下来累计的祖先贡献和都是不一样的,恰好对应每个历史版本。具体学了再说(我不会主席树,我好菜啊,我是 114514 流选手)。 - 树套树。首先,每个节点内的信息都是一个树,如果有上传操作的话,恭喜你获得了 (mathrm O!left(n^2log^2 ight)) 的优秀数据结构。考虑一路改下来避免上传。再来看区间修改的问题:如果懒标记,每个懒标记显然也是树,下传也是可以获得优秀复杂度的。考虑标记永久化,标记依然是树,不过不用进行下传操作了。上下传操作都没有了,查询的时候算贡献并不需要整棵树都保留,只需要截取查询区间的贡献,也就保证了复杂度了。
其他不能用懒标记而能用标记永久化的情况。