我们通过两次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 +...
对它进行重链剖分,将会得到这样的结果。(其中,绿色实线指的是重边,虚线指的是轻边,画得比较壮烈...) 这样就完成了重链剖分。 前置数据 下面是重链剖分需要用到的一些数据。 intdad[N];// 父亲节点intdep[N];// 深度intsiz[N];// 子树节点个数intson[N];// 重儿子inttop[N];// 所在重链的顶...
1 重链剖分简介 1.1 重链剖分基本性质 树链剖分,就是把树分成若干条链,然后通过这些链来进行各种操作。同时树链剖分分为重链剖分和长链剖分,一般情况下,我们所说的树链剖分就是重链剖分。 重链的定义: 一个节点子树大小最大的点被称为这个节点的重子节点(又名重儿子,可能不存在),这个点到它重子节点...
不妨设topx深度较小(否则交换x,y),则x∼topx的路径上不可能有x,y的LCA,直接修改[dfntopx,dfnx],然后将x跳到x所在重链链头的父节点,然后继续修改,直至满足条件 1,退出修改。 已证明,修改的复杂度为O(logn)。 事实上,这也引出了用重链剖分在O(logn)的时间复杂度下求LCA的方法,具体可以看这。
模板题: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...
重儿子 是指当前节点的所有儿子中子树最大的儿子 重链 全部由重儿子组成的链 接下来要进行的第一步 剖分树 剖分树需要有一个标准 这样才可以准确的知道这个树形结构是如何剖分的 这个标准就是 重儿子 这样就能剖出重链 将重链去掉后 再循环这个步骤
这种操作也被称为(轻)重链剖分。对于每个节点的儿子中,size 最大的为重儿子,其余为轻儿子,它到重儿子的边被称为重边,到轻儿子的为轻边。连续的重边会构成重链,我们在重链上连续编号。这样对于每段连续的编号都可以用线段树进行区间的修改/询问,复杂度为log。同时,根据定义很容易发现 size[i的轻儿子] < ...
vector<int>g[maxn];intson[maxn];//重儿子编号intid[maxn];//新编号intfa[maxn];//父亲节点intcnt;intdep[maxn];intsize[maxn];//子树大小inttop[maxn];//当前链顶节点intw[maxn];//初始点权数组intwt[maxn];//线段树部分structnode {intl,r; ...
轻重链剖分,常被称为树链剖分,是一种常用的维护树上信息的算法。 它以子树大小为依据,将节点划分为重儿子与轻儿子,从而使整棵树被剖分成若干条重链。 每个轻儿子都是一条重链的开始。一个节点只在一条重链上。 从树上任意一点到根节点,最多经过 \log n 条连续的链。 利