「雅礼集训 2018 Day4」Magic
题目
题解
本部分转载于 这位大佬
题中要求本质不同的序列数量,不太好搞。我们考虑给相同颜色的牌加上编号,这样所有牌都不相同。那么如果我们求出了答案,只需要将答案除以 \(\prod a_i!\) 就好了。
“恰好有 \(k\) 对”不能直接求,考虑容斥,如果我们求出了 \(g(x)\) 表示至少有 \(x\) 对的方案数,那么答案即为 \(\sum_\limits{i = k}^{n} (-1)^{i - k}\binom{i}{k}g(i)\)。现在的问题是如何求 \(g(x)\)。
我们将这 \(k\) 个魔术对分配到 \(m\) 种颜色中去,即:第 \(i\) 种颜色含有 \(b_i\) 个魔术对(满足 \(b_i < a_i\))。接下来可以做一个 dp,依次考虑每一种颜色,设 \(f_{i, j}\) 表示考虑了 \(i\) 种颜色,且已有 \(j\) 个魔术对的方案数。对于 \(i\),我们需要计算第 \(i\) 种颜色有 \(b_i\) 个魔术对的方案数是多少。由于我们已经视所有牌均不同,因此我们可以从中任选 \(b_i\) 张牌来作为所有魔术对的第二张牌,方案数为 \(\binom{a_i}{b_i}\)。接下来依次将这 \(b_i\) 张牌插入到原序列中去。由于必须插到相同颜色的牌的后面,因此第一张牌有 \(a_i - b_i\) 个位置可以插入,第二张牌有 \(a_i - b_i + 1\) 个位置可以插入......因此总方案数为 \(\binom{a_i}{b_i} \times (a_i - b_i)(a_i - b_i + 1)\cdots(a_i - 1) = \binom{a_i}{b_i} \times \frac{(a_i - 1)!}{(a_i - b_i - 1)!}\)。这样,我们只需枚举 \(b_i\) 然后转移即可。
不过注意这样求得的 \(f_{m, x}\) 并不是最终的 \(g(x)\)。由于构成魔术对的 \(x\) 张牌已经确定,不构成魔术对的 \(n - x\) 张牌可以任意排列,因此 \(g(x) = f_{m, x} \times (n - x)!\)。
这样做 dp 的复杂度是 \(\mathcal O(nm)\) 的,可以过 64 分。
注意到上面的 dp 其实是做了 \(m\) 次卷积,因此我们可以使用 NTT 进行优化。不过直接做 \(m\) 次多项式乘法时间复杂度并不能得到优化,注意到 \(f_{i, j}\) 中 \(j\) 一维的上界是不断合并增大的,因此我们可以使用一个堆,每次取出长度最小的两个数组进行 NTT 合并即可,这样复杂度就有保证了,时间复杂度为 \(O(m \log^2n)\)。