[算法学习笔记] 树链剖分(重链剖分)

news/2024/7/7 17:19:12/文章来源:https://www.cnblogs.com/SXqwq/p/18276175

概述

树链剖分能将一棵树剖分成若干条链的形式。从而能在树上用一些线性数据结构如线段树,树状数组等维护。树链剖分分为重链剖分,长链剖分,LCT 剖分等。最常用的是重链剖分。本文将讲解重链剖分。

本文将持续更新。

我们接下来给出一些定义。

  • 重儿子:指一个节点所有儿子中,子树最大的儿子。

  • 轻儿子:指一个节点除了重儿子其他的儿子。

  • 重边:连接一个节点和它重儿子的边。

  • 轻边:连接一个节点和它轻儿子的边。

image

(图源 https://blog.csdn.net/qq_41418281/article/details/108220247 ,侵删。)

在上图中,红色的节点即为重儿子,红色的边为重链。黄色的点和黄色的边分别对应其轻儿子和轻链。

实现

实现重链剖分,我们需要两边 dfs。第一遍 dfs 预处理出重儿子,每个节点的父节点(便于后面操作),子树大小(重儿子),节点深度(便于后面操作)。

第二遍 dfs,我们找到每条重链的链头(top)

这里给出参考代码。

重链剖分
void dfs1(int p, int d)
{int size = 1, ma = 0;depth[p] = d;for (auto q : Edge[p])if (!depth[q]){dfs1(q, d + 1);f[q] = p;size += siz[q];if (siz[q] > ma)son[p] = q, ma = siz[q];}siz[p] = size;
}
void dfs2(int p)
{
//    cout<<u<<"qwq"<<endl;;for(auto q:Edge[p]){if(!top[q]) {if(q == son[p]) top[q] = top[p];else top[q] = q;dfs2(q);}}
}

性质

通过上图,不难发现,重链是一条以轻儿子为链头的一条链(根节点除外),而轻链是连接重链与重链之间的桥梁。每个重链的链头的父亲一定在另外一条重链上。因此,我们记录每个节点的父亲,每条链的链头,就能快速实现重链与重链之间的跳跃。

其次,每个节点最多只能位于一条重链上。且一棵节点数量为 \(n\) 的树,从树上任意一条节点走到根节点,所经过的轻边数量不超过 \(\log n\) 条。

剖分完成后,我们便能在树上实现快速跳跃,重链剖分求解 LCA 是一种典型应用。下文将讲解。

重链剖分求 LCA

下文假设要求 \(a,b\) 的 LCA。

首先,若 \(a,b\) 位于同一条链上,则 LCA 即为深度较小的那个点。

若不在同一条链上。则 LCA 要么在链头深度较小的那条链上,要么就是两个链头的 LCA。绝不可能在链头深度较大的链上。这很显然,一条链只有到了链头才有轻边与其他重链连接。因此,我们不断让链头深度较大的往上跳到上一条链,直到到达同一条链为止。

具体实现见代码。

重链剖分求 LCA(省去重链剖分部分)
int lca(int a,int b)
{if(a > b) swap(a,b);while(top[a] != top[b]){//   cout<<a<<" "<<b<<endl;if(depth[top[a]] > depth[top[b]]) a = f[top[a]];else b = f[top[b]];}return (depth[a] > depth[b] ? b : a);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/734122.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net8,全网首发:部署为自带环境的前后端分离项目,编译成二进制机器码,防止反编译

环境:win10+.net8+vs2022+vue3(history路由模式)本文只演示在winows上面的部署 目的: 1.防止反编译,增加破解成本 2.更便捷的部署方式,开箱即用 实现: 1.不依赖容器,包括IIS,apache,docker,nginx等 2.更少的文件,所有dll逻辑打包成一个exe文件(如果是win环境是exe…

第7-8次大作业总结

前言: 第七次大作业: 这次大作业中新增了,两个新部件,一个是互斥开关,一个是受控窗帘,互斥开关意味着要用一个电器同时参与两条电路的构建,刚开始我没想好怎么去实现一个电器对两条支路,输出不同的状态,后来想到,不如直接把两个普通开关作为互斥开关的两个属性,把它…

配置自己的免费云主机,阿贝云,免费虚拟主机,免费云服务器

延期需要您在第三方网站发布使用感受,以下是对发布内容的详细要求: (1)比较推荐免费免费云主机,阿贝云,免费虚拟主机,免费云服务器 (2)“阿贝云”"免费虚拟主机"“免费云服务器”,配置使用比较方便简单,正在尝试更多功能,后续使用后再来继续发表 (3)可以…

OOP 7-8总结

oop 7~8总结 前言知识点 整体的知识点与前几次的题目没有太多的不同,每次迭代因为题目要求都有增加,所以会新增一些做法,但是像是继承、集合框架、正则表达式、抽象类、多态以及接口等知识点依然会重复使用,只是用法会不同。 越写到后面我越是意识到算法的重要性。在题目里…

家居强电电路模拟程序的两次迭代(包含最终版本)

目录: 一)前言 二)设计与分析 三)踩坑心得 四)改进建议 五)总结 (2)家居强电电路模拟程序-3: 【1】知识点:ArrayList的运用,物理知识的运用。 【2】题量:较大 【3】难度:较难 在家居强电电路模拟程序的迭代中引出较难的互斥开关 (3)家居强电电路模拟程序-4: 【1】…

免费的数据可视化(PCA、t-SNE和UMAP)网页程序

这是一款免费的数据可视化(PCA、t-SNE和UMAP)网页程序,直接进行在线操作,无需下载。这是一款免费的数据可视化网页程序,直接进行在线操作,无需下载。 URL: https://data-visualization-webapp-by-shuaibingli.streamlit.app/ 总体页面【预处理+可视化(PCA、t-SNE和UMAP)+保…

养老院视频监控智能分析系统

养老院视频监控智能分析系统为养老院提供先进的视频监控智能分析技术手段,构建养老智慧监控和安全智能分析防范体系,用科技手段弥补传统方法和技术在监管中的缺陷,变被动“监督”为主动“监控”。致力于打造智慧养老院,打造人性化托养、智能化运营管理,为各大养老机构减少…

关于nchu题目集7~8的总结

关于nchu题目集7~8的总结 一、前言 总结两次题目集的题目的知识点、题量、难度等情况 二、内容[题目[1]](##第三次题目(简略版)) [代码[2]](##我的代码) [设计与分析[3]](##设计与分析) [踩坑心得[4]](##踩坑心得) [改进建议[5]](##改进建议)题目集8最后一题(简略版)1、控制…

springboot+vue前后端分离项目-vue项目搭建5

1.改造登录vue/src/views/LoginView.vue,登陆后存储user信息到sessionStorage,进入到login页面移除sessionStorage里的user 2.改造vue/src/components/Header.vue,从sessionStorage中获取user,每个人登陆后根据个人信息显示名称 3.增加vue/src/views/Person.vue,点击个人信…

生产环境部署Nginx服务器双机热备部署-keepalived(多种模式教程)

前言:今天演示下生产环境keepalived的部署方式,安装模式有很多,比如说主备模型和双主模型,主备分:抢占模式 和 非抢占模式。这里我会一一展开说具体怎么配置 一、双节点均部署Nginx: 第一步:上传安装包到/usr/local/ 第二步:安装编译依赖(使用普通用户需要家sudo) yu…

无业游民写的最后一个.net有关项目框架

理想很丰满,现实往往很残酷。 一种按照ddd的方式,根据业务来把自己需要的模块一个一个写出来,再按照模块把需要的接口一个一个的写出来,堆砌一些中间件,以及解耦的command,handler等等 ,一个项目就这么成型了。上面的项目有一个非常清晰的特点,就是按需开发,不需要去可…

OOP第三次Blog

前言: (1) 第七次题集只有一道题目——家居强电电路模拟程序-3,这是第三次迭代,这次迭代主要的点有四个。 ​ 首先本次迭代添加了线路中存在多个串联起来的并联电路。不同于上次的单并联,本次更复杂。 ​ 然后本次还新迭代了一种控制器——互斥开关,互斥…

23201829OO第三次blog作业

OO第三次blog作业 前言 这次blog是本学期最后一次回顾总结,本次blog的范围是“家居强电电路模拟程序”的第三和第四次迭代,分别加入了互斥开关、窗帘的概念、多个串联起来的并联电路、串联电路中包含其他串联电路的情况和串联电路中包含串联电路的情况和二极管。因此这两次PT…

企业做账流程详解

都说会计月底很忙,那究竟都在忙什么呢,一起来看看吧

快速提取视频字幕!适用B站、AI字幕等等。好用

快速提取视频字幕!适用B站、AI字幕等等。好用 以B站为例: 视频教程:快速提取视频字幕!适用B站、AI字幕!非常好用_哔哩哔哩_bilibili 无论是视频的字幕,还是AI字幕,都可以提取。比较简单。 首先好像需要确定 视频的字幕还是AI字幕。如果是视频字幕,下面F12之后,输入的是…

Ymodem协议说明

Ymodem流程介绍1.Ymodem帧格式 Ymodem两种帧格式: 1024数据格式帧:名称 帧头 包号 包号反码 信息块 校验简写 SOH PN XPN DATA CRC字节数 1 1 1 128 2128数据格式帧:名称 帧头 包号 包号反码 信息块 校验简写 STX PN XPN DATA CRC字节数 1 1 1 1024 21.1 帧头 帧头一个有两…

CentOS7.9部署Nginx

简介 本章节主要讲的是在Linux系统CentOS7.9上去完成Nginx Web服务安装部署 步骤 1.配置 Nginx 源 2.yum 安装 Nginx 3.启动 Nginx 4.浏览默认站点 实施 1.配置 Nginx 源// 执行如下命令 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el…

CF132E Bits of merry old England

传送门构图好题。郑哥的题解 每一个输出的位置看作先分配变量(赋值或者用前面的),再输出。 给每个位置拆三个点 \(v_{i,1/2/3}\)。\(v_{i,1}\) 的流入表示这个位置的 "空变量" 数量(包括有值但是我们选择让它不重复使用的变量);\(v_{i,2}\) 有流入表示分配好了…

opp7~8题目集的反思与总结

opp7~8题目集的反思与总结 1、前言: 这两个题目集都是对于电路题目的迭代,都是对于电路题目的应用,对于电路的题目集,在上次的opp的题目集中就已经简述过了,没有看过的可以点击链接查看(opp第二次blog) 在这个里面就是之前的opp的题目集,讲述了大致的内容,这个是基础,…

CentOS7.9部署.NET Core 8.0

简介 本章节主要讲的是在Linux系统CentOS7.9上去完成.NET Core 8.0软件的安装,确定Linux的版本是x64还是arm64的,然后到.NET Core的官网下载8.0的SDK,并进行安装 步骤 1.查看系统版本 2.打开.NET Core 8.0下载网址 3.下载与Linux系统对应版本的.NET Core SDK 4.上传.NET Cor…