P5666 [CSP-S2019] 树的重心

考虑一个结点在什么情况下会成为重心。

随便钦定一个根结点。对于结点 u,假设割掉了其子树 v 中的某条边或连接 uv 的边,形成了一棵大小为 k 的新树。

mx 表示除 v 子树外最大的子树大小(或 nsizu)。如果 u 成为了重心根据定义有 2×max(mx,sizvk)nk

整理一下就变成 2×sizvnkn2×mx

对于割掉 u 子树外面的边的情况,类似可以得出 2×max(mx,nsizuk)nk

整理一下就变成 n2×sizukn2×mx

对于前一种情况,dsu on tree 维护一个树状数组计算可以割掉的子树数量。

对于后一种情况,先将全部子树扔进树状数组,然后在 DFS 的过程中不断更新(和换根 DP 一样)。不过我们只能得到当前子树内和子树外的和,所以得在前面 dsu on tree 的时候提前减掉子树内的部分。

注意上界大部分都是一样的,后一种情况的下界则都是一样的,所以可以记下来避免多次查询,常数会变小很多。

当然两只 log 赛场上不一定过得去,考虑继续优化。


发现要维护的信息可以直接进行简单的加减得到,所以没有必要使用 dsu on tree,依次累加,离开某个子树时的答案减去进入该子树时的答案即是该子树内的答案。

我真是个傻逼

还有 O(n) 做法,好像是直接考虑重心的移动过程,具体可以去看题解。

posted @   御坂夏铃  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示