我们通过两次dfs来进行重链剖分。第一趟dfs,先得到每个节点的fa(父节点)、sz(子树大小)、dep(深度)、hson(重子节点): void dfs1(int p, int d = 1) { int size = 1, ma = 0; dep[p] = d; for (auto q : edges[p]) if (!dep[q]) { dfs1(q, d + 1); fa[q] = p; size +...
1 重链剖分简介 1.1 重链剖分基本性质 树链剖分,就是把树分成若干条链,然后通过这些链来进行各种操作。同时树链剖分分为重链剖分和长链剖分,一般情况下,我们所说的树链剖分就是重链剖分。 重链的定义: 一个节点子树大小最大的点被称为这个节点的重子节点(又名重儿子,可能不存在),这个点到它重子节点...
不妨设topx深度较小(否则交换x,y),则x∼topx的路径上不可能有x,y的LCA,直接修改[dfntopx,dfnx],然后将x跳到x所在重链链头的父节点,然后继续修改,直至满足条件 1,退出修改。 已证明,修改的复杂度为O(logn)。 事实上,这也引出了用重链剖分在O(logn)的时间复杂度下求LCA的方法,具体可以看这。
对它进行重链剖分,将会得到这样的结果。(其中,绿色实线指的是重边,虚线指的是轻边,画得比较壮烈...) 这样就完成了重链剖分。 前置数据 下面是重链剖分需要用到的一些数据。 intdad[N];// 父亲节点intdep[N];// 深度intsiz[N];// 子树节点个数intson[N];// 重儿子inttop[N];// 所在重链的顶...
模板题:https://www.luogu.com.cn/problem/P3379本视频讲了:树链剖分求LCA 、DFS序转RMQ求LCA, 视频播放量 2893、弹幕量 5、点赞数 107、投硬币枚数 74、收藏人数 91、转发人数 24, 视频作者 幻想家协会会长, 作者简介 前杭二教育集团信息学竞赛教练!研究算法竞赛十年!
树链剖分详解 转载请注明出处,部分内容引自banananana大神的博客 树链剖分就是将树分割成多条链,然后利用数据结构(线段树、树状数组等)来维护这些链。 前置知识: dfs序 LCA 线段树 先来回顾两个问题: 1,将树从x到y结点最短路径上所有节点的值都加上z 这也是个模板题了吧 我们很容易想到,树上差分可以以O...
重儿子 是指当前节点的所有儿子中子树最大的儿子 重链 全部由重儿子组成的链 接下来要进行的第一步 剖分树 剖分树需要有一个标准 这样才可以准确的知道这个树形结构是如何剖分的 这个标准就是 重儿子 这样就能剖出重链 将重链去掉后 再循环这个步骤
重链:相邻重边组成的一条链称为重链。 规定对于叶子节点,如果它是轻儿子,则以它自己为起点有一条长度为 1 的重链。 每一条重链的起点是轻儿子。(所以根应该是轻根) (图片来自 chinhhh 的博客,侵删。) 预处理 树链剖分的预处理有先后两个 dfs 实现,我们暂且叫 dfs1、dfs2 。
因此重链剖分重点在如何解决树上路径修改问题,考虑将树划分成若干条链,分别对每条链进行修改、查询操作,便可实现树上路径修改 为简化问题,先考虑根结点到某结点的路径,我们不希望看见该路径涉及成过多条链的情况,而将树划分成重路径和轻边可以很好地解决这一问题 首先给出重儿子和轻儿子的定义:...
这种操作也被称为(轻)重链剖分。对于每个节点的儿子中,size 最大的为重儿子,其余为轻儿子,它到重儿子的边被称为重边,到轻儿子的为轻边。连续的重边会构成重链,我们在重链上连续编号。这样对于每段连续的编号都可以用线段树进行区间的修改/询问,复杂度为log。同时,根据定义很容易发现 size[i的轻儿子] < ...