浅析树链剖分Orz

本文思路参考自何开大佬

引子

相信各位大佬一定会线段树这种非常实用的数据结构

那么如果我们要维护一棵树上的链的权值的时候怎么办

就比如说BZOJ1036树的统计这道题目

可能诸位草率地想想线段树是可以口头AC的,But 这是在一棵树上,线段树支持的连续的区间操作

在这棵树上,如果链的编号断断续续,那么我们的线段树就和暴力没有什么区别有一点点区别了

概念

所以这里就需要用到树链剖分,这种可以支持树上链操作的数据结构

树链剖分有很多高大上的名词需要我们去记

我们先定义一些概念东东

size[u]表示以u为根的树的大小

dep[u]表示u的深度(根的深度定为1)

fa[u]表示u的爸爸(???)

有了这些东东,我们开始定义真正的概念

重儿子:u的所有儿子v中,size[v]最大的v称为u的重儿子

轻儿子:u的所有儿子v中,不是重儿子的都被叫做轻儿子

重边:u 连向它的重儿子的边称为重边

沁轻边:u连向它的轻儿子的边称为轻边

重链:组成这条链的所有的边都是重边

沁轻链:组成这条连的所有边都是轻边

一些小性质

性质1:V为u的轻儿子,则必有size[V] <= size[u] / 2

这个性质证明可以用到反证法

如果存在V为轻儿子并且size[V] > size[u] / 2

我们会发现如果一个节点成为重儿子的条件就是size[V] >= size[u] / (SonNumber[u])      //SonNumber[u]表示u的儿子的数目

因为size[u] / 2 > size[u] / 3 > size[u] / 4 ………………………………

而且size[V] 是不可能大于size[u]的

所以,V为这时候只能为重儿子

与假设不符

证毕~~~~

性质2:从根到某一节点的路径上,轻边的数量不超过O(log N),重链的数目不超过O(log N)

这个我们也是可以证明的

因为我们可以从性质1直接推得轻边的数量不超过O(log N)

后来我们发现

没存在一条轻边,就会出现两条重链

所以重链的数量不超过O(log N)

证毕~~~~

操作

时间: 2024-08-04 16:31:11

浅析树链剖分Orz的相关文章

浅析树链剖分

前言 树链剖分,我觉得最精妙的地方就在于它是通过$dfs$序将树形结构转为线性结构便于处理,进而可以用数据结构(线段树.树状数组等)去进行修改和查询. 将复杂的结构转化为相对我们熟悉简单的结构,这个思想对很多问题是通吃的,不仅仅在树形问题,算法中,在其他领域中也常常会用到这种思想 我们先来回顾两个问题: 1.将树从$x$到$y$结点最短路径上所有节点的值都加上z 我们很容易想到,树上差分可以以 $O(n+m)$的优秀复杂度解决这个问题 2.求树从$x$到$y$结点最短路径上所有节点的值之和 $l

BZOJ 1969: [Ahoi2005]LANE 航线规划( 树链剖分 )

首先我们要时光倒流, 倒着做, 变成加边操作维护关键边. 先随意搞出一颗树, 树上每条边都是关键边(因为是树, 去掉就不连通了)....然后加边(u, v)时, 路径(u, v)上的所有边都变成非关键边了, 因为形成了环, 环上任意2点有2条路径...下图, 加上蓝色的边, 红色x的边就变成了非关键边. 所以树链剖分维护一下...时间复杂度O(NlogN+MlogM+Qlog^2N), 可以AC. 翻了翻ZY的标解:“动态维护树+最近公共祖先查询”....复杂度是O(NlogN+M+QlogN)

BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status][Discuss] Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LC

树链剖分 [HDU 3966] Aragorn&#39;s Story

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3544    Accepted Submission(s): 995 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lord

【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] Description 别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求你在这棵树上维护两种事件 事件0: 这棵树长出了一些果子, 即某个子树中的每个节点都会长出K个果子. 事件1: 小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝

【块状树】【树链剖分】bzoj1036 [ZJOI2008]树的统计Count

很早之前用树链剖分写过,但是代码太长太难写,省选现场就写错了. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 #define lson rt<<1,l,m 6 #define rson rt<<1|1,m+1,r 7 #define maxn 60000 8 int n,m,u,v; 9 int V[maxn],Next[

2017博普杯 东北大学邀请赛(B. Drink too much water)(贪心+树链剖分)

题目地址:https://oj.neu.edu.cn/problem/1204 题目大意: 其实就是树上的线段覆盖, 给出一棵n个结点的树,然后给出树上的一些路径进行覆盖,然后要求选取最少的点,能够把这些线段都占有 (或者说:一开始树上每个结点权值都为0,选取最少的点,把它们的权重变成1,使得询问的每一条路径上有含有权值为1的结点) 题解: 类似线段覆盖(线段覆盖是按照右端点贪心) 这个题就是按照每个路径的lca的深度贪心 也就是说把询问按照lca的深度从大到小排序 然后依次枚举询问 如果当前询

BZOJ2157: 旅游 树链剖分 线段树

http://www.lydsy.com/JudgeOnline/problem.php?id=2157 在对树中数据进行改动的时候需要很多pushdown(具体操作见代码),不然会wa,大概原因和线段树区间修改需要很多pushup是一样的. 这个轻重链的方法特别好用,虽然第一次写树链剖分但是容易理解又有优秀复杂度的结构让人情不自禁orz. (后来发现很久以前学lca的时候就学了树链剖分只不过忘了,mdzz) 因为忘了去掉测试代码的freopen,re了4次(虽然有三次就算不re也wa),发现一

树链剖分算法解析

本文部分内容参考自 这篇博客 (写的很好 Orz ,建议大家也去看一下) 树链剖分是什么?用来做什么? 有一棵树,求解以下问题:1将从 x 到 y 的路径上的每个结点权值增加 z2求从 x 到 y 的路径上的每个结点的权值和/权值最大值/权值最小值 单独求解每个问题都很简单,这两种问题结合起来,之前的方法就变得并不理想了. 而树链剖分可以巧妙地解决这一类问题. 树链剖分概述 树链剖分可以把一棵树分割成几条链, 原文地址:https://www.cnblogs.com/abc2237512422/