题意:给定长度为 序列 ,每次随机选择 ,将 加上 ,然后让 减 1。问 次操作后, 的期望。,,对 取模。
首先给出一个结论:
表示前后 乘积的变化量。这个可以通过分每一步看来得到,既然单步是正确的,那么合并起来也是正确的。
现在显然是求变化后的期望。
考虑使用 EGF 计算每一步改变的哪一个位置,然后合并。单个的 EGF 可以写作:。
那么最后变化后的期望就是:
不是封闭形式不好计算,考虑对每一个 变换来尝试得到封闭形式:
这样就变成的封闭形式。
乘起来可以得到:
后面这个式子可以 计算,但是直接 DP 计算每一位也不是不行。
下面对后面是贡献 时 的系数计算:
虽然 很大,但是 不大,这些都可以约到 项,而且不同的 可以递推计算,所以这不是难事,可以在 或者 的时间内求出所有 的贡献。
总时间复杂度 ,狗都不写 MTT。注意代码中的 f[t]
求的是 的系数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| int main() { std::cin >> n >> k; for (int i = 1; i <= n; ++ i) std::cin >> a[i]; f[0] = 1; for (int i = 1; i <= n; ++ i) for (int j = i - 1; ~j; -- j) f[j + 1] = (f[j + 1] + (LL) f[j] * a[i]) % Mod; int res = 0, cur = k; for (int i = 1; i <= n && i <= k; ++ i) { if (!(i & 1)) res = (res + (LL) (Mod - cur) * qpow(n, k - i) % Mod * f[n - i]) % Mod; else res = (res + (LL) cur * qpow(n, k - i) % Mod * f[n - i]) % Mod; cur = (LL) cur * (k - i) % Mod; } res = (LL) res * qpow(n, Mod - 1 - k) % Mod; std::cout << res << '\n'; return 0; }
|
Related Issues not found
Please contact @mydcwfy to initialize the comment