题目所求为每个连通块的第 k 大权值之和,相当于枚举 w=1…W 求满足第 k 大权值不小于 w 的连通块个数,又相当于枚举 w=1…W 求满足不小于 w 的权值至少有 k 个的连通块个数。
枚举 w,设 fu,w(i) 表示在以 u 为根的子树内选择一个包含 u 的连通块,满足其中不小于 w 的权值有 i 个的方案数。
考虑合并 u 和儿子 v 的状态: f′u,w(i)=fu,w(i)+i∏j=0fu,w(j)fv,w(i−j) (为了美观,假设 i<0 时 fu,w(i)=0。)
设 Fu(x) 表示 fu 的生成函数,则有 F′u,w(x)=Fu,w(x)(1+Fv,w(x))
考虑按照点值计算,则枚举 x=1…n+1,利用线段树按照 w 维护整体 DP。
为了保证复杂度,同时需要维护 Gu,w(x) 表示 ∑p∈subtree(u)Fp,w(x)。
对于每个点,一开始时 Fu,w(x)=x[du≥w]。
则考虑在线段树上维护变换 (a,b,c,d) 表示 (f,g)→(af+b,g+cf+d)。
则容易合并两个变换 (a1,b1,c1,d1),(a2,b2,c2,d2) 为 (a1a2,b1a2+b2,c1+a1c2,b1c2+d1+d2)
此外,你需要一个 O(n2) 的拉格朗日插值。
如果点值形如 (i,yi) 的话,可以考虑范德蒙德矩阵求逆。
不过可以首先暴力计算出 x−xi 的乘积(注意这是一个 n+1 次多项式),然后每次模拟一下多项式除法即可计算 ∏i≠j(x−xj)。
大常数选手不开 O2 过不去(
代码:
1 |
|