【模板】分治FFT

题意

分析

如果我们已经求得了 f[L],f[L+1] ... f[mid],他们均能对f[mid+1],f[mid+2]...,f[R]产生贡献

对于x ∈ [mid+1,r] f[x] += \sum_{i=L}^{mid}(f[i]*g[x-i])

等式右边满足卷积模式

具体看代码

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int n;
 5 ll gg[400005],f[400005],A[400005],B[400005];
 6 int g=3,mod=998244353;
 7 ll qpow(ll a,ll b) {
 8     ll res=1;
 9     while(b) {
10         if(b&1) res = res * a % mod;
11         a = a*a %mod;
12         b >>= 1;
13     }
14     return res;
15 }
16 int rev(int x,int r) {
17     int ans=0;
18     for(int i=0;i<r;i++) if(x&(1<<i)) ans+=1<<(r-i-1);
19     return ans;
20 }
21 void ntt(int n,ll a[],int on) {
22     int r = 0;
23     while((1<<r)<n) r++;
24     for(int i=0;i<n;i++) {
25         int tmp = rev(i,r);
26         if(i < tmp)  swap(a[i],a[tmp]);
27     }
28     for(int s=1;s<=r;s++) {
29         int m = 1<<s;
30         ll wn=qpow(g,(mod-1)/m);
31         for(int k=0;k<n;k+=m){
32             ll w=1;
33             for(int j=0;j<(m>>1);j++) {
34                 ll t = w * a[k+j+(m>>1)] % mod;
35                 ll u=a[k+j];
36                 a[k+j] = (u+t)%mod;
37                 a[k+j+(m>>1)] = (u-t)%mod;if(a[k+j+(m>>1)]<0)a[k+j+(m>>1)]+=mod;
38                 w = w*wn%mod;
39             }
40         }
41     }
42     if(on==-1) {
43         for(int i=1;i<(n>>1);i++) swap(a[i],a[n-i]);
44         ll inv = qpow(n,mod-2);
45         for(int i=0;i<n;i++) a[i] = a[i] * inv % mod;
46     }
47 }
48 void solve(int l,int r) {
49    if(l == r) return;
50    int mid = (r+l)>>1;
51    solve(l,mid);
52    int siz = r-l+1;
53    int len = 1;
54    while(len < siz+siz) len <<=1;
55    for(int i=0;i<len;i++) A[i] = B[i] = 0;
56    for(int i=l;i<=mid;i++) A[i-l] = f[i];
57    for(int i=1;i<=r-l;i++) B[i] = gg[i];
58     ntt(len,A,1);ntt(len,B,1);
59     for(int i=0;i<len;i++) A[i]=A[i]*B[i]%mod;
60     ntt(len,A,-1);
61     for(int i=mid+1;i<=r;i++) f[i] = (f[i] + A[i-l])%mod;
62     solve(mid+1,r);
63 }
64 int main() {
65     ios::sync_with_stdio(false);
66     cin >> n;
67     for(int i=1;i<n;i++) {
68         cin >> gg[i];
69         gg[i] %= mod;
70     }
71     f[0] = 1;
72     solve(0,n-1);
73     for(int i=0;i<n;i++) cout<<f[i]<<" ";
74     cout<<"\n";
75 }

 

posted @ 2018-11-30 22:35  Greenty  阅读(275)  评论(0编辑  收藏  举报