给 dp 编组合意义转为 GF 问题,利用多项式操作优化.
考虑朴素 dp , 设 $dp(i,j)$ 表示考虑了前 $i$ 个元素,选了 $j$ 个到子序列中的权值之和,则有
$$
dp(i,j)=(c_i+j)\cdot dp(i-1,j-1)+dp(i-1,j)
$$
如果 $c_i=0$ ,这个递推式和第二类斯特林数很像,考虑把 $j$ 这一维变换一下,凑成相同的形式.
显然当 $i\ge j$ 时 $dp(i,j)$ 才可能有值,可以做一个变换,令 $dp(i,j)$ 表示原来的 $dp(i,i+j)$ ,变为
$$
dp(i,j)=(i-j+c_i)\cdot dp(i-1,j)+dp(i-1,j-1)
$$
可以给这个 dp 编一个类似第二类斯特林数的组合意义,将至多 $i$ 个元素分到 $j$ 个非空集合中:
- $(i+c_i)\cdot dp(i-1,j)$ 表示第 $i$ 个元素没有被加入任何一个集合,贡献为 $i+c_i$ .
- $-j\cdot dp(i-1,j)$ 表示第 $i$ 个元素加入了已有的 $j$ 个集合之一,产生了 $-1$ 的贡献.
- $dp(i-1,j-1)$ 表示第 $i$ 个元素单独占据了新的一个集合.
枚举有 $k$ 个元素没有加入任何一个集合,答案为
$$
ans=\sum_{k=0}^n ([x^k]\prod_{i=1}^n((c_i+i)x+1)) \cdot f_{n-k}
$$
其中 $f_i=\sum dp(i,j)$ 表示有 $i$ 个数加入了集合中的贡献总和,求出每个 $f_i$ 即可算出答案.
由于一个数加入之前已有的集合时会有 $-1$ 的贡献,相当于最后要乘上 $(-1)^{i-j}$ , $i$ 表示元素数, $j$ 表示集合数.
可以先令这个系数为 $(-1)^j$ ,那么就是 $dp(i,j)=(-1)^j\cdot {i\brace j}$ 最后再对每个 $f_i$ 乘上 $(-1)^i$ 即可.
第二类斯特林数关于列 $j$ 的 EGF 为 $\frac {(\exp(x)-1)^j}{j!}$ , 那么 $dp(i,j)$ 关于列 $j$ 的 EGF 就是 $\frac {(1-\exp(x))^j}{j!}$ .
$$
f_i=\sum_{j} dp(i,j)\\
f_i=\cdot\sum_{j} i!\cdot[x^i] \frac {(1-\exp(x))^j}{j!}\\
f_i=i!\cdot[x^i] \sum_j \frac {(1-\exp(x))^j}{j!}\\
f_i=i!\cdot[x_i] \exp((1-\exp(x))
$$
做一次多项式 exp 求出所有的 $f_i$ ,前面的 $\prod_{i=1}^n((c_i+i)x+1)$ 用分治 NTT 计算,时间复杂度 $O(n\log^2 n)$ .
可以用分治 NTT 实现多项式 exp ,这里不是复杂度瓶颈.
1 | //%std |