无根树分治的三种常见方法
无根树分治一般常见于树上路径问题(计数,最优化等).
常见题目如
无权树树上距离为 \(k\) (对 \([1,n)\) 求) 的路径数量.
点分黑白且可以改,求两端都是黑点的最远路径.
以我的理解,三种分治是无法互相平替的.
三种分治复杂度均为 \(T(n)\log n\).
其中 \(T(n)\) 为处理规模为 \(n\) 的子问题的开销,且满足 \(T(x)+T(y) \le T(x+y)\).
点分治
一个点直接计算贡献.
否则每次取重心,计算重心儿子之间的贡献.
然后去掉重心再分治子树.
复杂度证明
重心的重儿子大小不超过一半,每次分治最大规模至少减半,由此可证.
若超过一半重心可向较重那侧偏移,一定更优.
问题:信息会被分成多个部分.(不允许虚点虚边则边修较困难)
边分治
先三度化(度数大于3的拆虚点虚边.常见实现类似左儿子右兄弟.)
一个点直接计算贡献.
每次取一条边满足两侧中较大那侧最小.
计算两侧的贡献,去掉这条边后分治两侧的连通块(连通块还是树).
复杂度证明
考虑三度化后的重心,该点到其重儿子的连边.
显然重儿子那侧不会小于 $\dfrac{1}{3}$ 且不会大于 $\dfrac{1}{2}$.
所以一次分治最大规模至少减少 $\dfrac{1}{3}$,由此可证.
因此也发现如果不三度化的话,菊花就会卡掉.
问题:需要虚点虚边.
1/3 分治
不知道中文名叫啥,1/3 是个明显特征,就先这么称呼吧.
如果树的大小不超过 \(2\) 直接处理.
否则,每次取重心 \(u\),把重心的子树分成两个集合\(S,T\)(每颗子树只处于一个集合内),考虑两个集合之间的贡献.
然后分治到点集是 \(S\cup u\), \(T\cup u\) 的两个问题.
复杂度证明
复杂度基于一定存在一种选取方式使较小的集合的大小大于等于1/3.
而且可以直接贪心,随意按一个顺序枚举,如果加入这个儿子所在的子树后大小仍小于等于2/3就加入.
两个儿子的情况由重心性质即得.
三个儿子的话会取最小和次小两个,满足条件.
多于三个儿子可合并最小的两个儿子转换成儿子更少的情况.
这样不可能使原本无解变得有解,也不可能创造大于1/2的儿子.
(不过这种情况下贪心的严格正确性还得细证一下,可以自己思考:)
这样的话,每次分治最大规模(按边计)至少减少 $\dfrac{1}{3}$,由此可证.
这个分治过程没有保证某个点的出现次数(hack:菊花).
但保证了边的出现次数,实际上 1/3 分治类似于不实际创造虚点虚边的边分治.
问题:难以点修.