题解:AT_abc399_f [ABC399F] Range Power Sum
__mt19937__ · · 题解
题目链接
这次的F题有点难度,估计可以评个绿题吧。
思路
此题可以用DP+二项式定理解决。
我们设
dp_{r + 1, k} = \sum^{r + 1}_{i = l} (\sum^{r + 1}_{i = l} A_i)^k \space\space\space\space\space\space\space\space \space\space\space\space\space = A_{r + 1}^k + \sum^r_{i = 1} (\sum^r_{i = 1} A_i + A_{r + 1}) ^ k
然后根据二项式定理
如果我们将
那么原式就变成了:
\space\space\space\space A_{r + 1}^k + \sum^r_{l = 1} \sum^r_{i = l} \binom{k}{j} (\sum^k_{j = 1}A_i) ^ j A_{r + 1} ^ {k - j} =A_{r + 1}^k + \sum^k_{j = 1} \binom{k}{j} \sum^r_{l = 1} (\sum^r_{i = l} A_i) ^ j A_{r + 1} ^ {k - j}
然后观察一下中间的这个式子
所以最后的转移方程就长这样:
dp_{i + 1,j} = A_{r + 1}^k + \sum^k_{j = 1} \binom{k}{j} dp_{r, j}
最终的结果就是
代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
const int Mod = 998244353;
signed main (void) {
std :: ios :: sync_with_stdio (false);
std :: cin.tie (nullptr);
std :: cout.tie (nullptr);
int N, K;
std :: cin >> N >> K;
std :: vector <int> A (N + 1);
for (int i = 1; i <= N; ++ i) {
std :: cin >> A[i];
}
std :: vector <std :: vector <int> > F (K + 1);
F[0].resize (K + 1);
F[0][0] = 1;
for (int i = 1; i <= K; ++ i) {
F[i].resize (K + 1);
F[i][0] = F[i][i] = 1;
for (int j = 1; j < i; ++ j) {
F[i][j] = F[i - 1][j] + F[i - 1][j - 1] % Mod;
}
}
std :: vector <int> Result (K + 1), Presult (K + 1), Comb (K + 1);
int Answer = 0;
for (int i = 1; i <= N; ++ i) {
Comb[0] = 1;
for (int j = 1; j <= K; ++ j) {
Comb[j] = Comb[j - 1] * A[i] % Mod;
}
for (int k = 0; k <= K; ++ k) {
Result[k] = Comb[k];
for (int j = 0; j <= k; ++ j) {
Result[k] = (Result[k] + Presult[j] * F[k][j] % Mod * Comb[k - j]) % Mod;
}
}
Answer += Result[K];
Answer %= Mod;
Presult = Result;
}
std :: cout << Answer << endl;
return 0;
}
完结撒花🎉🎉🎉