题解:P14461 【MX-S10-T2】『FeOI-4』青年晚报
williamwei · · 题解
来一篇只用组合意义,不需要找规律的题解。
根据题面,先写出这两个多项式
注意到会导致
通过代入计算可以得知多项式
观察这个式子,考虑一组运算后系数的组合意义:以
为了方便推导,反过来思考,考虑从最终位置向上走:假设有
所以
最后考虑有剩余运算的情况(
预处理逆元,因为
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 5000 + 10;
const int mod = 1e9 + 7;
int n, m, f[maxn], g[maxn], F[maxn], G[maxn], c[maxn], fac[maxn], inv[maxn];
int qpow(int a, int b) {
int res = 1; for (; b; b >>= 1, a = (ll)a * a % mod)
if (b & 1) res = (ll)res * a % mod; return res;
}
void calc(int* f, int* F) {
for (int i = 0; i <= m; i++)
for (int j = 0; i + (j << 1) <= m && j <= n; j++)
F[i] = (F[i] + (ll)(j & 1 ? -1 : 1) * f[i + (j << 1)] * c[j] % mod * fac[i + (j << 1)] % mod * inv[i]) % mod;
}
int main() {
ios::sync_with_stdio(false);
cin >> n >> m; fac[0] = inv[0] = 1;
for (int i = 0; i <= m; i++) cin >> f[i];
for (int i = 0; i <= m; i++) cin >> g[i];
for (int i = 1; i <= m; i++) fac[i] = (ll)fac[i - 1] * i % mod, inv[i] = qpow(fac[i], mod - 2);
// 处理奇数情况:单独进行一次操作
if (n & 1) {
for (int i = 0; i <= m; i++) F[i] = (g[i] + (ll)(i + 1) * g[i + 1]) % mod,
G[i] = (f[i] - (ll)(i + 1) * f[i + 1]) % mod;
for (int i = 0; i <= m; i++) f[i] = F[i], g[i] = G[i], F[i] = G[i] = 0;
} n >>= 1;
// 预处理组合数 C(n, j) = n * (n - 1) * ... * (n - j + 1) / j!
for (int i = 0; i <= m; i++) {
c[i] = inv[i];
for (int j = n; j > n - i; j--) c[i] = (ll)c[i] * j % mod;
} // 计算经过 k 组操作后的 F 和 G
calc(f, F); calc(g, G);
for (int i = 0; i <= m; i++) cout << (F[i] + mod) % mod << ' '; cout << '\n';
for (int i = 0; i <= m; i++) cout << (G[i] + mod) % mod << ' '; cout << '\n';
return 0;
}