【NTT】loj#6261. 一个人的高三楼 【计数】cf223C. Partial Sums

去年看过t老师写这题博客;以为是道神仙题

题目大意

求一个数列的$k$次前缀和。$n\le 10^5$.


题目分析

【计数】cf223C. Partial Sums 加强版。注意到最后的式子是$f_i=\sum\limits_{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\n",f[i]);
68     return 0;
69 }

END

猜你喜欢

转载自www.cnblogs.com/antiquality/p/10555059.html
今日推荐