zoukankan      html  css  js  c++  java
  • 【模板】分治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<<"
    ";
    75 }
  • 相关阅读:
    deepin-wine-tim 字体发虚
    windows&linux双系统时间相差8小时
    Linux 禁用 ipv6
    双系统win10更新后无法进入linux
    Failed to receive SOCKS4 connect request ack 解决
    zsh 使用通配符功能
    vux修改css样式的2种办法
    Ubuntu 16.04 安装OpenSSH7.4
    Nginx开启http2访问和gzip网页压缩功能
    vue开发环境和生产环境里面解决跨域的几种方法
  • 原文地址:https://www.cnblogs.com/greenty1208/p/10046894.html
Copyright © 2011-2022 走看看