长链剖分优化 dp
前言
- 对于一类树上 \(dp\) 问题,有一个维度有关 深度 的时候,也许可以用长链剖分优化
长链剖分优化流程
-
首先以向下的最大深度为基础对于每个点求出重儿子
-
在 \(dp\) 转移的时候,对于重儿子因为有一个维度是深度,那么直接利用指针 \(O(1)\) 继承自己的重儿子的信息
-
对于轻儿子就遍历一遍最大深度暴力合并 \(dp\) 的信息
-
可以发现对于每一条链都仅会在自己的链顶端被 \(O(链长)\) 暴力合并一次,并且记录的信息也是 \(O(链长)\),所以空间和时间的复杂度都可以优化到 \(O(n)\)
-
不过长链剖分优化的题目难点似乎应该也不会在长链剖分上
例题
给定一张无向图,求有多少个点对满足点对之间的必经点的个数为 \(L\),\(n\leq 2e6,m\leq 4e6\)
-
首先用圆方树转成树上问题,那么就是问树上两个点之间圆点的个数为 \(L\) 的点对个数
-
虽然不是严格的深度,但是第二维可以看成一个有关深度的问题,所以显然可以用长链剖分优化到 \(O(n)\)
-
一些废话:不过我是先打完小常数 dsu (
虽然带了一支 \(\log\) ,但是富贵险中求)觉得也许可以过后突然想到长链剖分可以直接优化到 \(O(n)\)(这个确实是正解),然而不想改了,不过 dsu 真的过了... 是数据太水了还是机子太快了,我自己当时手搓的大数据一般都是在 1.9s 左右(崩溃的边缘徘徊),不知道是否有人淀粉质搞过去了,翻了一下代码好像真的有?数据过水....(应该卡掉大常数 log 放过我的小常数)