树剖1.重链剖分

重链剖分维护的是重儿子和由一系列重儿子形成的链
重儿子就是当前节点的子节点中子树节点最多的那个子树的根节点
于是就讲了个大概

板子

题目描述
如题,已知一棵包含 N 个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作:

  • 1 x y z,表示将树从 xy 结点最短路径上所有节点的值都加上 z
  • 2 x y,表示求树从 xy 结点最短路径上所有节点的值之和。
  • 3 x z,表示将以 x 为根节点的子树内所有节点值都加上 z
  • 4 x 表示求以 x 为根节点的子树内所有节点值之和

于是我们的重链剖分就开始了
子树上的问题可以借助树上差分应付一下,但是路径?
树链剖分+数据结构

树链剖分

顾名思义就是把一棵树划分成若干链
它的好处就是可以把树上的问题转化为区间问题求解
分为重链和长链两种,这里讲重链

Prework

重链剖分的预处理分为两步:
1.求出重儿子
2.重新标号同时划分重链

树上的问题不难想到用DFS解决
第一步是一个不用教也会打的东西
主要分析第二个DFS,重标号和重链划分

树上问题转化为区间,用到的一个利器就是DFS序
这里用DFS序重新标一下号
把当前节点标号,完成以后
优先标记重儿子,确保各个重儿子形成一条重链
这里保证了时间复杂度和dfs序的连续性,便于上数据结构维护信息
时间复杂度:
可以发现,当我们向下经过一条轻边时,所在子树的大小至少会除以二。
因此,对于树上的任意一条路径,把它拆分成从lca分别向两边往下走,分别最多走log次,因此,树上的每条路径都可以被拆分成不超过log条重链。

重链DFS完以后递归轻儿子就行了
重标号就可以建立DFS序到原节点标号的映射,也方便区间修改查询

修改

子树修改

在维护节点信息时额外维护了子树的大小
根据DFS序的性质可以知道子树的DFS序连续
所以直接上区间查询线段树就行了

路径修改

顺带着就可以把维护LCA写了
如果两个节点不在一条重链上就往上跳到重链顶端
(反正不在同一条重链上的跳到顶端必不相遇)
如果到了顶端那么挑一个深度浅的就是LCA
在跳重链的时候顺便就把路径信息就修改了
因为一条重链在预处理的时候是连续的,
所以重链上就可以上区间数据结构维护一下(线段树平衡树分块等等)
正确性是在重标号上,因为重标号完了以后两个节点是一样的

查询

查询基本上是同理的
然后框架也是一致的
然后原题要取模注意一下

细节

维护区间信息,线段树,分块和平衡树都比较可以
然后就是线段树维护的不同信息
然后就是预处理和建树

边转点:(边权转点权)
可以用树上差分的方式,把边权改成父节点到子节点增加的部分
这个时候直接把边权打在子结点上就行了

换根:(continue)

posted @   2K22  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示