Description
在幻想乡白玉楼有一棵终年不开花的樱树叫西行妖,西行寺幽幽子曾经为了让它开花而大量收集春度,然后被城管教训了一顿…
现在,幽幽子得到城管的允许,收集了S点春度,让西行妖重新开花。
西行妖可以被看成是一棵有n个节点的树,每个叶子节点被分配了1点春度就能开花(幽幽子不会无意义地使用她的春度,于是最多只会给同一个叶子节点分配1点春度),对于非叶子节点i,如果它有至少有1个儿子开花,那么节点i能开花。
据说,西行妖的花开满之时,幽幽子会复活。但是城管只给了S点春度(S≤20),所以幽幽子这次是抱着娱乐的心态种树的。
如果西行妖有至少m个节点开花,那么幽幽子认为它是美丽的。现在幽幽子想知道,有多少种方案,使西行妖是美丽的(答案对10^9+7取模)。
注意:幽幽子不一定会把S点春度都分配完。
Solution
一看就知道是一个DP题
设f[i][j][k]表示在第i个叶子节点,用了j个春度,k个节点开了花
转移很显然f[i][j][k]=∑f[l][j−1][k−(deep[i]−deep[lca(i,l)])]
如果叶子节点乱序的话,会对DP造成影响,所以叶子节点最好用dfs序来排一个序。
O(n3s)70分
优化
如果直接用dfs序的顺序来转移,那么一颗子树中lca的深度是递增的。
为了运用这个性质方便转移,所以我们设s[j][k][d]=∑f[l][j][k],d表示所有lca(i,l)深度为d,光用s还不能转移,观察一下方程,再设cnt[j][k−d]=∑s[j][k][d],那么f[i][j][k]=cnt[j−1][k−deep[i]]
我们只要在访问每个叶子节点的时候更新f,并用更新之后的f来更新s和cnt。
每次搜完i的所有子节点时,再向上传递后,原来lca深度为d,现在变成了d-1,所有还要把s[j][k][d-1]的值更新,并清空s[i][]j[d],并继续更新cnt数组。
xdl司机春度是什么鬼
xdl:不知道,番上的翻译是这样的。
Code