P13682 [IAMOI R2] 污水博弈
神秘数数题。
我们考虑计算所有区间的贡献。
我们记
-
-
$$\frac{s_r}{r}\sum\limits_{i=2}^{n-r+1}\frac{1}{i}\binom{n-r-1}{i-2}=\frac{s_r}{r}\sum\limits_{i=0}^{n-r-1}\frac{1}{i+2}\binom{n-r-1}{i}$$ -
$$\frac{s_n-s_{l-1}}{n-l+1}\sum\limits_{i=2}^{l}\frac{1}{i}\binom{l-2}{i-2}=\frac{s_n-s_{l-1}}{n-l+1}\sum\limits_{i=0}^{l-2}\frac{1}{i+2}\binom{l-2}{i}$$ -
$$\frac{s_r-s_{l-1}}{r-l+1}\sum\limits_{i=3}^{n-r+l+1}\frac{1}{i}\sum\limits_{j=1}^{l-1}\binom{l-2}{j-2}\binom{n-r}{i-j-1}$$ 后半部分是一个范德蒙德卷积,于是贡献为: $$\frac{s_r-s_{l-1}}{r-l+1}\sum\limits_{i=3}^{n-r+l+1}\frac{1}{i}\binom{n-r+l-2}{i-3}=\frac{s_r-s_{l-1}}{r-l+1}\sum\limits_{i=0}^{n-r+l-2}\frac{1}{i+3}\binom{n-r+l-2}{i}$$
发现复杂度瓶颈在于
我们当然可以 NTT 做完,但那样太不牛了。
考虑如下化简:
次数太高没法做,但是这题
当
当
至此,我们在
代码很短。
#include "iostream"
#define int long long
using namespace std;
const int maxn=11e5+5,P=998244353;
int inv[maxn],s[maxn],pw[maxn],g[maxn],h[maxn],f[maxn];
inline int fp(int a,int k) {
int r=1;
for(;k;k>>=1,a=a*a%P) if(k&1) r=r*a%P;
return r;
}
inline void init(int n) {
pw[1]=2; inv[1]=pw[0]=1;
for(int i=2;i<=n;++i) inv[i]=inv[P%i]*(P-P/i)%P,pw[i]=2*pw[i-1]%P;
}
inline int G(int u) { // \sum_{i=0}^{u} \binom{u}{i}\frac{1}{i+3}
if(u<0) return 0;
return ((pw[u+3]*inv[u+3]-pw[u+3]*inv[u+2]+pw[u+1]*inv[u+1]
-inv[u+3]+2*inv[u+2]-inv[u+1])%P+P)%P;
}
inline int H(int u) { // \sum_{i=0}^{u} \binom{u}{i}\frac{1}{i+2}
if(u<0) return 0;
return ((pw[u+2]*inv[u+2]-pw[u+1]*inv[u+1]
-inv[u+2]+inv[u+1])%P+P)%P;
}
signed main() {
ios::sync_with_stdio(0);
int n,ans=0,lim; cin>>n; init(n+10);
for(int i=1;i<=n;++i) {
cin>>s[i],s[i]=(s[i-1]+s[i])%P;
g[i]=G(n-i-2); h[i]=H(n-i-1);
}
ans=(s[n]*inv[n])%P; lim=(n-1)/2;
for(int i=1;i<n;++i) ans=(ans+h[i]*s[i]%P*inv[i])%P;
for(int i=n;i>1;--i) ans=(ans+h[n-i+1]*(s[n]-s[i-1]+P)%P*inv[n-i+1])%P;
for(int i=1;i<=lim;++i) f[i]=(s[n-i]-s[i]+f[i-1]+P)%P,f[n-i-1]=f[i];
for(int i=1;i<n-1;++i) ans=(ans+inv[i]*f[i]%P*g[i])%P;
cout<<ans*fp(pw[n-1],P-2)%P;
return 0;
}