最后五分钟过掉成功翻盘,纪念一下。

首先发现,如果要最大化价值,所选出的 kk 个点一定在树上形成一个连通块。

证明过程考虑调整,如果不形成联通块,则一定可以找到一个点,将它向黑点最多的方向移动一条边(满足目标节点没有黑点),这样操作之后,其他边的价值不变,而这条边的价值增加了 22,而形成连通块之后,没有任何一个点可以这样调整。

而且,我们还发现,对于一个 kk,如果一条边不在点形成的连通块内,则它的价值一定是 kk,这样的边有 (n1)(k1)=nk(n - 1) - (k - 1) = n - k 条,所以这部分的贡献与树的形态无关,为 k(nk)k(n - k)

于是问题接下来就变成,对于每个 kk,都求出一个连通块最大化它内部的价值。

我们先考虑对于一棵全是黑点的树,这个价值怎么简单的算。如果对于每条边模拟计算,这样的价值带绝对值不便维护,所以考虑对于价值做适当的变换去掉绝对值。

把树定根,这样,价值就变成 urtszu(kszu)\sum_{u \ne rt} |sz_u - (k - sz_u)|,也就是 urtk2szu\sum_{u \ne rt} |k - 2sz_u|,我们发现,当 szu>k2sz_u > \frac k2 时,(u,fau)(u, fa_u) 这条边的价值才是 2szuk|2sz_u - k|。于是取这棵树的任意一个重心rtrt,则价值就变成了 urtk2szu\sum_{u \ne rt} k - 2sz_u,即 k(k1)2urtszuk(k - 1) - 2\sum_{u \ne rt} sz_u

这时,我们就可以换根树上背包来求后式(就是这个 urtszu\sum_{u \ne rt} sz_u)的最小值了(换根是因为要钦定根为重心),但是不好做也没必要。

考虑分别计算每个点 vv 对后式的贡献,则每个 vv 的祖先 uu(包括 vv 自己)都会在后式当中统计到它一次,而这个统计的次数也就是 vv 的深度 depvdep_v(即 rtvrt \to v 经过的边数),所以后式等价于 vrtdepv\sum_{v \ne rt} dep_v(实际上 deprt=0dep_{rt} = 0,所以 vrtv \ne rt 这个限制是没用的)。

得到这个式子,这道题也就做完了,因为重心实际上还有另外一个性质,也就是满足树上所有的点到它的距离之和最小,所以钦定非重心为根的答案一定不优。

通过这个性质,我们直接对每个根 rtrt 算出选 kk 个点的答案并取最小值即可。

对于每个根算答案可以做到 O(n)O(n),则时间复杂度为 O(n2)O(n^2)

code