去年看过t老师写这题博客;以为是道神仙题
题目大意
求一个数列的$k$次前缀和。$nle 10^5$.
题目分析
【计数】cf223C. Partial Sums 加强版。注意到最后的式子是$f_i=sumlimits_{j+k=i}pre_j a_k$的样子,因此在预处理$pre_j$之后就是卷积的板子了。
1 #include<bits/stdc++.h> 2 #define MO 998244353 3 const int maxn = 400035; 4 const int inv3 = 332748118; 5 6 int n,len,dt; 7 int cov[maxn],a[maxn],f[maxn],pre[maxn],fac[maxn],inv[maxn]; 8 long long k; 9 10 int qmi(int a, int b) 11 { 12 int ret = 1; 13 for (; b; b>>=1, a=1ll*a*a%MO) 14 if (b&1) ret = 1ll*ret*a%MO; 15 return ret; 16 } 17 void NTT(int *a, int opt) 18 { 19 for (int i=0; i<len; i++) 20 if (i < cov[i]) std::swap(a[i], a[cov[i]]); 21 for (int i=1; i<len; i<<=1) 22 { 23 int Wn = qmi(3, (MO-1)/(i<<1)); 24 if (opt==-1) Wn = qmi(inv3, (MO-1)/(i<<1)); 25 for (int j=0, p=i<<1; j<len; j+=p) 26 { 27 int w = 1; 28 for (int k=0; k<i; k++, w=1ll*w*Wn%MO) 29 { 30 int valx = a[j+k], valy = 1ll*w*a[i+j+k]%MO; 31 a[j+k] = (valx+valy)%MO, a[i+j+k] = (valx-valy+MO)%MO; 32 } 33 } 34 } 35 if (opt==-1){ 36 int inv = qmi(len, MO-2); 37 for (int i=0; i<len; i++) a[i] = 1ll*a[i]*inv%MO; 38 } 39 } 40 void init() 41 { 42 pre[0] = fac[0] = fac[1] = inv[0] = inv[1] = 1; 43 for (int i=2; i<=n; i++) 44 fac[i] = 1ll*fac[i-1]*i%MO, 45 inv[i] = MO-1ll*(MO/i)*inv[MO%i]%MO; 46 for (int i=1; i<=n; i++) 47 pre[i] = 1ll*pre[i-1]*(k%MO+i-1)%MO*inv[i]%MO; 48 } 49 int main() 50 { 51 freopen("loj6261.in","r",stdin); 52 freopen("loj6261.out","w",stdout); 53 scanf("%d%lld",&n,&k); 54 for (int i=0; i<n; i++) scanf("%d",&a[i]); 55 if (k){ 56 init(); 57 for (len=1; len<=n+n; len<<=1) ++dt; 58 for (int i=0; i<len; i++) 59 cov[i] = (cov[i>>1]>>1)|((i&1)<<(dt-1)); 63 NTT(a, 1), NTT(pre, 1); 64 for (int i=0; i<len; i++) f[i] = 1ll*a[i]*pre[i]%MO; 65 NTT(f, -1); 66 }else for (int i=0; i<n; i++) f[i] = a[i]; 67 for (int i=0; i<n; i++) printf("%d ",f[i]); 68 return 0; 69 }
END