题解:AT_abc399_f [ABC399F] Range Power Sum
Fire_flame · · 题解
题目传送门
\mathtt{Solution}
简单题。
观察这个式子的形式,发现它可以用二项式定理拆开。
记
由于
由于
赛时代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int s = 0, f = 1;char ch = getchar();
while(!isdigit(ch)){if(ch == '-')f = -1;ch = getchar();}
while(isdigit(ch)){s = s * 10 + ch - '0';ch = getchar();}
return s * f;
}
void write(int x){
if(x < 0){putchar('-'); x = -x;}
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
const int MAXN = 2e5 + 5, MOD = 998244353;
int n, k, ans, a[MAXN], s[MAXN], fac[MAXN], inv[MAXN], sum[MAXN];
int fpow(int a, int b){
int res = 1;
while(b){
if(b & 1ll)res = res * a % MOD;
a = a * a % MOD;
b = b >>= 1ll;
}
return res;
}
int C(int x, int y){
if(x < y)return 0;
return fac[x] * inv[y] % MOD * inv[x - y] % MOD;
}
signed main(){
n = read(), k = read();
for(int i = 1;i <= n;i ++)a[i] = read(), s[i] = (s[i - 1] + a[i]) % MOD;
fac[0] = 1;
for(int i = 1;i <= 2e5;i ++)fac[i] = fac[i - 1] * i % MOD;
inv[200000] = fpow(fac[200000], MOD - 2);
for(int i = 2e5 - 1;i >= 0;i --)inv[i] = inv[i + 1] * (i + 1) % MOD;
for(int i = 0;i <= n;i ++){
for(int j = 0;j <= k;j ++){
ans += C(k, j) * sum[j] % MOD * fpow(-1, j) % MOD * fpow(s[i], k - j) % MOD;
ans %= MOD;
ans += MOD;
ans %= MOD;
sum[j] += fpow(s[i], j), sum[j] %= MOD;
}
}
printf("%lld\n", ans);
return 0;
}