[AtCoder Toyota2023 Spring Final] Git Gud

发布时间 2023-11-22 17:32:58作者: kyEEcccccc

拜谢 Magic Duck 大神。其次我很喜欢洛谷逆天翻译把大翻译成小……

首先考虑算一下贡献,考虑每个点的深度,一开始都是 1,进行合并以后相当于首先把两个端点的深度累计到答案里,然后再选择一边给它的联通块内每个点深度增加 1。那么容易发现我们可以算贡献转化为每个联通块权值为它向外的度数,每次合并任意选择一边将它的权值累积进答案(当然一定选择大的那边),然后合并两联通块。那么合并联通块度数相加还会损失 2,这里的一个技巧是把权值设为度数减二,这样就可以直接相加了。最后再把答案加上 \(2n - 2\),这是因为合并次数是已知的。于是这个问题得到了比较好的转化。

考虑一个结论:任何一次合并不会选择两个已经被合并过的联通块将它们合并。随便考虑四个块排成一排,发现总是能构造出一种依次合并进某个块的顺序,使得它优于分别合并两边再合并中间的边的方案。那么最优的合并顺序一定是选择一个根,然后依次把下面的节点合并进根里。此外,我们不妨假设任何一次合并时,根处的权值都大于被合并的另一个权值,否则换成下面那个点为根一定更优。

于是枚举这个根,问题变成了给定一棵有根树,每个点有点权,给每个点赋 \([1, n]\) 内互不相同的整数系数,要求父亲系数大于儿子,最大化系数乘点权的和。这是经典问题,考虑权值最大的点标号一定等于它父亲的标号减一,那么直接考虑把它合并进父亲,于是每个点有一个大小和一个权值和,我们容易发现它的“等效权值”就是它的权值和除以它的大小。于是用并查集之类的随便合并一下就可以了。