无根树分治的三种常见方法

无根树分治一般常见于树上路径问题(计数,最优化等).

常见题目如

无权树树上距离为 \(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 分治类似于不实际创造虚点虚边的边分治.

问题:难以点修.

posted @ 2024-06-19 20:31  QedDust  阅读(64)  评论(0)    收藏  举报