题解:AT_arc120_f [ARC120F] Wine Thief
ARC120F
简要题意: 求所有大小为
解法:
带着贡献数数不好做,拆贡献。考虑
那么自然令
如何算出
考虑一种类似容斥的做法,既然
我们发现这个和式的项中和
总时间复杂度
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mod=998244353;
inline int Mod(int x) { return x<0 ? x+mod : (x>=mod ? x-mod : x); }
inline void adm(int &x,int y) { x=Mod(x+y); }
inline int qmi(ll a,int b)
{
ll res=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) res=res*a%mod;
return res;
}
const int N=600010;
int n,k;
int a[N];
int fac[N],infac[N];
void init(int M=N-1)
{
fac[0]=1;
for (int i=1;i<=M;i++) fac[i]=(ll)fac[i-1]*i%mod;
infac[M]=qmi(fac[M],mod-2);
for (int i=M-1;~i;i--) infac[i]=(ll)infac[i+1]*(i+1)%mod;
}
int binom(int a,int b)
{
if (a<0 || b<0 || b>a) return 0;
return (ll)fac[a]*infac[b]%mod*infac[a-b]%mod;
}
int f(int a,int b) { return binom(a-b+1,b); }
int sum[N];
int main()
{
int buf;
cin >> n >> k >> buf;
for (int i=1;i<=n;i++) cin >> a[i];
init();
for (int i=1;i<=n;i++)
{
int cof=f(n-4*i+1,k-2*i+1);
sum[i]=Mod(sum[i-1]+cof);
}
int ans=0;
for (int i=1;i<=n;i++)
{
int mxj=min((i+1)/2,(n-i+2)/2);
int s=(mxj ? sum[mxj-1] : 0);
auto calc = [&](int j)
{
int cut=n-4*j+1+((i-2*j+1==0)+(i+2*j-1==n+1));
int cof=f(cut,k-2*j+1);
return cof;
};
adm(s,calc(mxj));
//cout << i << " " << s << "\n";
adm(ans,(ll)a[i]*s%mod);
}
cout << ans << "\n";
return 0;
}