首页 > 其他分享 >长链剖分总结

长链剖分总结

时间:2023-03-27 20:18:40浏览次数:51  
标签:总结 长链 剖分 链长 祖先 leftarrow 重链

长链剖分总结

长链剖分,顾名思义,就是按照链长(即深度)把树剖成若干条链。具体的,定义每个点的儿子中,子树深度最大的点是重儿子,不断跳重儿子形成的链也就是重链。

长链剖分的性质:

1.从一个点向上跳重链的次数不会超过\(\sqrt n\)次。

证明:考虑每跳到一条新的链上,这条链一定比前一条链长,而最坏情况下,才有重链长度分别为\(1,2,3,\cdots\sqrt n\),因此最多不会跳超过\(\sqrt n\)条重链。

2.任意一个点的\(k\)级祖先所在的重链的长度大于等于\(k\)

证明:如果\(k\)级祖先所在的链长度小于\(k\),又因为这个点到\(k\)级祖先这条链已经长于原先的重链了,而这是不可能的,故任意一个点的\(k\)级祖先所在的重链的长度大于等于\(k\)。

长链剖分的应用

1.\(O(n\log n)-O(1)\)求树上\(k\)级祖先

根据刚刚的性质,我们令\(k'=\frac{k}{2}\),那么\(x\)的\(k'\)级祖先所在的重链长度不小于\(k'\),那么就可以知道\(x\)的\(k\)级祖先在条重链上了,然后我们预处理出倍增数组和小于链长次祖先,询问时就可以做到\(O(1)\)了。

例题:

【模板】树上 k 级祖先

2.优化和深度有关的树形DP

思路类似\(\text{dsu on tree}\) ,每次从重儿子那里继承信息,再额外计算轻儿子的贡献。

例题:

1.CF1009F Dominant Indices

题意:给定一棵有\(n\)个节点的树,设\(d(x,k)\)为点\(x\)的子树内与\(x\)距离为\(k\)的点数,对于每个点,求出使\(d(x,k)\)最大的\(k\)中最小的一个。

思路:考虑一个\(O(n^2)\)的DP,设\(f_{x,i}\)表示\(x\)的子树里与\(x\)距离为\(i\)的点的个数,转移时\(f_{x,i}\leftarrow f_{y,i-1}\)。我们尝试优化,即先从重儿子那里继承信息,再把轻儿子的信息暴力合并上去。我们可以发现,如果只看重儿子的话,那么就相当于把\(f_{y}\)错位对应上了\(f_{x}\),那我们就可以利用一种特殊的技巧,即动态分配DP数组的内存。具体来讲,我们为每条长链链顶申请长为链长的空间,然后链上的所有点共用这部分空间,即\(f_{y}\)的起点是\(f_{u}+1\),那这样就可以把时间和空间都减到\(O(n)\)的量级。这时我们再考虑把轻儿子的答案,合并上来,这样的复杂度也是\(O(n)\)的,因为每一条重链只会被合并一次,而且每一次合并是\(O(len)\)的(len是链长),总共加起来就是\(O(n)\)的。这样我们就成功地把\(O(n^2)\)优化到了\(O(n)\)。

2.[POI2014]HOT-Hotels

题意:求树上选择两两距离相等的3个点的方案数。

思路:先考虑朴素DP。设\(f_{x,i}\)表示点\(x\)的子树内与\(x\)距离为\(i\)的点的数量,\(g_{x,j}\)表示\(x\)的子树内满足\(d(u,lca(u,v))=d(v,lca(u,v))=d(x,lca(u,v))+i\)的点对数量,因此有转移:

\[ans\leftarrow f_{x,i-1}\times g_{y,i}\;,\;ans\leftarrow g_{x,i+1}\times f_{y,i}\;,\;f_{x,i}\leftarrow f_{y,i-1}\;,\;g_{x,i+1}\leftarrow g_{y,i}+f_{x,i+1}\times f_{y,i} \]

可以发现,\(f_x,g_x\)可以像上一道题一样直接从\(f_y,g_y\)移一位得到,那自然也可以用动态分配内存来优化,只是注意\(g_{son_x}=g_{x}-1\)意味着之前要多申请一倍空间。

3.[湖南集训]更为厉害

题意:多次询问,给定\(a,k\),求树上满足\(dis(a,b)\leqslant k\),且\(a,b\)都是\(c\)的祖先的点对\((b,c)\)的数量。

思路:这道题有114514种做法,之前用的是\(O(n\log n)\)的离线树状数组的做法,这里给出一个长剖的\(O(n)\)的做法。

首先考虑\(b\)不在\(a\)子树里的情况,这时\(b\)只能是\(a\)的祖先,那答案自然就是\(\min(dep[x]-1,k)\times(siz[a]-1)\)。

然后就是\(b\)再\(a\)子树里的情况,这时的贡献就是\(\sum\limits_{dis(a,b)\leqslant k}siz[b]-1\),看起来这个东西也可以类似地维护,只是需要维护重链上的后缀和,这样转移时就可以直接错位继承了。复杂度\(O(n)\)。

标签:总结,长链,剖分,链长,祖先,leftarrow,重链
From: https://www.cnblogs.com/Xttttr/p/17262667.html

相关文章

  • 地铁线路查询的总结分析
    设计思想:站点查询为数据库查询操作,通过输入站点名称,输出线路线路查询为数据库list查询操作,通过输入线路名称。输出当前输入线路所有站点最短路线为BFS广度优先遍历,输入起点......
  • 地铁线路查询的总结分析
    设计思想:站点查询为数据库查询操作,通过输入站点名称,输出线路线路查询为数据库list查询操作,通过输入线路名称。输出当前输入线路所有站点最短路线为BFS广度优先遍历,输入起点......
  • C++ primer第十五章总结
    1oop的思想是数据抽象继承和动态绑定数据抽象可以将类的接口与实现分离;继承动态绑定,又称运行时绑定2虚函数是基类希望其派生类进行覆盖的函数<1>任何构造函......
  • 算法总结--搜索
    声明(叠甲):鄙人水平有限,本文为作者的学习总结,仅供参考。1.搜索介绍搜索算法包括深度优先搜索(DFS)和广度优先搜索(BFS)这两种,从起点开始,逐渐扩大寻找范围,直到找到需要的......
  • 题目集1~3的总结性blog
    一.前言学期伊始,面向对象的程序设计课程的老师就利用PTA平台陆续发布了三次训练集。这三次训练集所涉及知识点与课上所学知识点有关,具体知识点如下:训练集01:此训练集所......
  • 红胖子创业第二年总结: 聚焦擅长优势,切勿盲目扩大,技术积累产品,减少无用社交,改变性格观
    前言  给自己创业第二年整的一个总结,2022.03.27~2023.03.26  分为多段:聚焦擅长优势,勿盲目扩大,技术积累做产品,减少无用社交,改变性格与观念,渐入佳境闭嘴,创业不是纯为......
  • 代码随想录Day13-Leetcode239. 滑动窗口最大值,347.前 K 个高频元素,栈和队列总结
    239.滑动窗口最大值一开始没有思路,暴力了,然后果然超时;看提示中的单调队列没有特别明白;后面反应过来跟单调栈很像;也确实很符合本题的情况,一旦队尾出现更大的数,前......
  • C# StackExchange.Redis 用法总结
    阅读目录安装 StackExchange.Redis引用及初始化String(字符串)List(列表)Hash(哈希)发布订阅事务Batch批量操作Lock(分布式锁)StackExchange.Redis封装安装 St......
  • PTA题目总结
    (1)前言:第一次题目集主要考察JAVA的一些语法知识,比如,控制台的输入,输出时保留两位小数,数组的使用,第十题有点难度,当时没写出来,现在想想 也还好,就是读懂题目有点费劲,第一次题......
  • 题集1-3总结
    一.前言题集一主要考察的是Java的基本语法,主要包括输入输出,选择(if-else)循环(while,for)结构,数组的使用,字符串的操作,基本数据类型(int,double,char,boolean)第十题难度较高,其余题难......