树上分治
1. 点分治
现在有一棵大小为 \(n\) 的树,要求出路径长度小于 \(k\) 的路径。
每次可以通过选择重心的方式,将整棵树分为一堆不大于 \(\dfrac{n}{2}\) 的子树,所以将整棵树分为大小为 \(1\) 的子树需要 \(\log n\) 次。
对于现在求出重心的子树,显然有三种情况可以组成一条路径。
- 路径两端点均在某一子树内
- 路径两端点在不同子树内
- 路径某一端点为重心
首先需要找出重心。
显然这个点不一定要是重心,只需要满足每个子树的大小不超过 \(\dfrac{n}{2}\) 即可。
记录每个点最大子树的大小即可,然后比较是否满足小于 \(\dfrac{n}{2}\)。
然后处理出每个子树到其子树内的距离。
最后用双指针扫一下每个子树里满足条件的路径有多少,用容斥显然就是总的数量减去每个子树中的数量。
代码实现:

浙公网安备 33010602011771号