首页 > 其他分享 >树链剖分【产品说明书】

树链剖分【产品说明书】

时间:2023-10-12 21:00:12浏览次数:37  
标签:剖分 线段 树链 修改 说明书 重链 节点

一种暴论:树链剖分 = 多叉树上分块 + 线段树


适用范围

总之就是数据结构的基础问题。
总的来说,树链剖分可以在\(O(m\log n)\)的时间复杂度中,解决大多数树上路径问题,包括其修改、维护和查询。

例如这样的一道模板题

又例如……(请直接跳到本文最后一章)


产品简介

树链剖分有两种:重链剖分,长链剖分。(按照剖分树的方式区分)

重链剖分中有如下一些定义:

重儿子:除叶子节点外,每个点的儿子中,子树最大(即子树节点最多)的子节点。(每个节点只有一个)
轻儿子:除叶子节点外,每个点的儿子中,不是重儿子的节点。(每个节点可能有不止一个)
重边:除叶子节点外,两端点都是重儿子的边。它用于构成重链。
轻边:除叶子节点外,每个节点到其轻儿子的边。它起到连接重链的作用。
重链:一些重边连成的链。
轻链:一些轻边连成的链。

而长链剖分,相当于将重链剖分中“子树大小”的部分替换为了“子树深度”,例如:

长儿子:除叶子节点外,每个点的儿子中,子树最深(即子树的层数最大)

综上,树链剖分是对树进行剖分,最终使其变成一些线性且不相交的链的算法。这时候,对树的操作,就变成了在链上的操作。
链可是经常作为部分分存在的好东西啊


生效原理

关于它的性质和实现方式。

树链剖分的性质

每个节点只能属于一条链,如果每次都选择节点更多的分支建链,建出的链自然会更长,从而,链的数量也就会更少。

由此,对于重链剖分,有这样的性质:
从根节点到任意一个叶子只需要经过\(O(\log_{2}n)\)条重链。
(因为每条轻边意味着树的大小至少缩小了一半。所以整棵树中,轻边的数量是\(O(\log_{2}n)\)的。而两条重链必然由轻边连接。)

它的另一个性质是:每条重链的DFS序是连续且有序的。
这一性质使重链得以被线段树维护。对于树上区间的修改查询问题,它“继承”了线段树的优势。

树链剖分的实现

详见代码解析(指路


使用范例

DFS序与线段树

我们知道两个性质:

  1. 每条重链内的DFS编号连续且有序
  2. 每棵子树内的DFS编号连续且有序

所以以DFS编号建立线段树。则同一条重链的节点,在线段树上是一个连续区间。

路径上的修改与查询

假设给出节点\(x\),\(y\),要修改/查询\(x\)到\(y\)最短路径上节点的权值。

这其实类似于求LCA的过程。(毕竟树上最短路径嘛)而这个过程又类似于ST表求LCA的过程。
不妨假设\(x\)链头深度更深,设\(dfn[u]\)表示节点\(u\)的dfs编号。

修改

首先,令\(x\)沿重链向上跳到链头。修改这段路径中的节点权值。(对应线段树中区间为\([dfn[x], dfn[链头]\))

然后将\(x\)跳到上方的重链,并再次执行上一操作。重复这两步,直到\(x\)与\(y\)的链头深度相同。

然后将\(x\)和\(y\)同时向上跳(类似上两步的方法),直到它们处于同一条重链之中。此时再修改\(x\)和\(y\)之间的节点即可。(对应线段树中区间为\([dfn[x], dfn[y]]\))

过程中的每次修改,直接调用update函数即可。

查询

路径查询和路径修改一模一样。只需要把update函数换成query函数。
(甚至可以用同一个求LCA函数实现查询&修改)

子树里的修改与查询

子树里的操作相比于路径更加简单。
一棵子树中节点的DFS序是连续且有序的,所以可以直接用线段树进行操作(当然,提前处理子树的\(l\)和\(r\))



完结撒花!

标签:剖分,线段,树链,修改,说明书,重链,节点
From: https://www.cnblogs.com/meteor2008/p/17760360.html

相关文章

  • 树链剖分
    树链剖分树链剖分常用于解决树上路径查询的问题。原理:对于树上两点之间的路径\(u\)->\(v\),根据某种策略,将之拆分成若干条链,然后利用线段树等数据结构单独维护这些子链,最后将答案合并。常用的剖分方法:轻重边划分。剖分树种的边可以分为两种边:重边和轻边。设\(size_u\)......
  • 算法:树链剖分
    去年就看过树链剖分的视频了,当时连树状数组,线段树都没学,对树的dfs也一知半解,所以基本完全听不懂。昨天又重新看了一般,感觉思路挺简单,应该比线段树简单吧,从用树链剖分求LCA来看确实是这样的,但是没有想到的是用线段树维护树链剖分。QAQ这应该是我打过最长的代码吧!(3K)树链剖分......
  • 浅谈树链剖分—轻重链剖分
    闲话似乎会有很多种树剖,什么长链剖分之类的,但是暂时只会轻重链剖分(可怜)。以前的版本在这里,但是感觉写的太粗糙了,所以决定重写一篇(我也不知道为什么要一直写树剖而不写点别的)。正文引入如果给出一个序列,有一些区间修改查询之类的操作,直接上线段树什么的就完事了,但是如果给出的......
  • Resctrl使用说明书
    前言Resctrl文件系统是Linux内核在4.10提供的对RDT技术的支持,作为一个伪文件系统在使用方式上与cgroup是类似,通过提供一系列的文件为用户态提供查询和修改接口。本文就resctrl文件系统的使用进行了详细说明,内容基本来自于LinuxDocumentation中的精华部分。使用限制与挂载检查......
  • 微软写了份GPT-4V说明书:166页详细讲解,提示词demo示例全都有
    克雷西萧箫发自凹非寺量子位公众号QbitAI多模态王炸大模型GPT-4V,166页“说明书”重磅发布!而且还是微软团队出品。什么样的论文,能写出166页?不仅详细测评了GPT-4V在十大任务上的表现,从基础的图像识别、到复杂的逻辑推理都有展示;还传授了一整套......
  • 树链剖分
    前言:本人太弱了,看着题解调了一下午,才A了树剖的板子题,所以写篇博客纪念一下(其实是怕自己忘了树剖怎么做)。本文以板子题为例子定义:树链剖分,计算机术语,指一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每个于且只属于一条链,然后再通过数据结构(树状数组、BST、SPL......
  • [学习笔记] 树链剖分
    叫复习笔记或许更好。树链剖分就是把树剖成链去解决一些问题。定义重子节点:子节点中子树大小最大的节点。轻子节点:除重子节点外的其他子节点。重边:到重子节点的边。轻边:到轻子节点的边。记号\(dfn[x]\):DFS序,也是在线段树中的编号。\(son[x]\):重子节点。\(dep[x]\)......
  • GPS北斗双系统NTP网络校时服务器技术参数说明书
    GPS北斗双系统NTP网络校时服务器技术参数说明书GPS北斗双系统NTP网络校时服务器技术参数说明书京准电子科技官微——ahjzsz欢迎使用安徽京准电钟电子科技有限公司自主研发生产的“HR-901GBNTP网络时间服务器”。HR系列服务器支持NTP和SNTP网络同步协议,是一款高精度、大容量、......
  • 「学习笔记」树链剖分
    树链剖分用于将树分割成若干条链的形式,以维护树上路径的信息。具体来说,将整棵树剖分为若干条链,使它组合成线性结构,然后用其他的数据结构维护信息。树链剖分有很多种形式,本文要讲的是其中的轻重链剖分。树链剖分本质上就是把链从树上砍下来,然后放到树状数组或线段树上来维护。......
  • 三国杀说明书
    三国杀说明书初衷本系统设计时已经最大程度考虑后继兼容性即不需要改变主代码框架也可以实现增加手牌种类(成员函数指针),增加英雄及其技能(继承Player类),增加游戏人数和玩法(存储玩家的和绝大多数函数设计上都是面向服务端的)但是该作品只是demo所以这次只实现了一个固定英雄郭嘉(......