专栏文章

题解:CF1205D Almost All

CF1205D题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miqb4vme
此快照首次捕获于
2025/12/04 01:55
3 个月前
此快照最后确认于
2025/12/04 01:55
3 个月前
查看原文

Almost All

首先吐槽一嘴,这个数据范围很奇怪,这题是可以做到 O(n)O(n) 的,可是 n1000n\leq 1000。这什么神操作?
先不管数据范围以及题目的要求。拿到这题,首先按照题意随意构造几个。如果是一条长度为 nn 的链,若边权全为 11 则可以构造出 [0,n1][0, n-1]。瞄一眼所求,发现是一个二次的式子,于是想到把这条链看作左右两段,想办法让它们乘起来,我们可以类似进制的操作。先按照前面所述的方法,设左边构造出 [0,a][0, a],右边构造出 [0,b][0, b],此时,将右边的边权全部乘上 a+1a+1,则右边变成了 0,a+1,2(a+1),,b(a+1)0, a+1, 2(a+1), \dots, b(a+1),再加上左边 [0,a][0, a],则可以构造出 [0,ab+a+b][0, ab+a+b] 的数。当然如果分成更多段,当 nn 大的时候可以做得更好,不过在此题没有必要。
再回过头看看题目要求,把 2n29\left\lfloor\frac{2n^2}{9}\right\rfloor 中的 2n29\frac{2n^2}{9} 看成 n3×2n3\frac{n}{3}\times\frac{2n}{3},则在一条链的情况,只需要把链分成长度比为 12\frac{1}{2} 的两段,当然比离 11 越近越好,就可以达到题目要求。那么,对于一般情况,只需要把整棵树拆成两棵分别用链的方法解决。
而对于单独一棵的贡献,若要从链的方法迁移,则能产生贡献的就是树上的节点到树根的链。比如操作子树 uu 时,对于两棵子树 v1,v2v1, v2,设子树 v1v1 可以做出 [0,a][0, a],子树 v2v2 可以做出 [0,b][0, b]。设边 (u,v1)(u, v1) 的边权为 ww(这是因为 v1v1 以前的子树已经表示出了 [0,w1][0, w-1]),则子树 v1v1 实际表示出了 [w,w+a][w, w+a]。那么给子树 v2v2 的值都加上 w+a+1w+a+1,即将 (u,v2)(u, v2) 的边权设为 w+a+1w+a+1,就可以最大化表示出的数的数量了。可以发现,一棵子树 uu 能产生的贡献为 sizeu1size_u-1,这个使用归纳法可证。则像做链的方法一样把子树 uu 分成两部分即可。
为了方便划分这两部分,可以先求出树的重心,此时将重心作为根,则每棵子树的大小都不超过 n2\left\lfloor\frac{n}{2}\right\rfloor,把子树按大小降序排,按顺序取子树,当取的总大小不小于 n3\left\lfloor\frac{n}{3}\right\rfloor 为止,则一定能分成大小差不超过 n3\left\lfloor\frac{n}{3}\right\rfloor 的两部分。
代码在此

评论

1 条评论,欢迎与作者交流。

正在加载评论...