• 分治fft


    鉴于fft的题在当今ICPC已经成为签到题了,还有很有必要掌握一些进阶应用。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define maxn 400005
    #define LL long long
    using namespace std;
    const int mod=998244353;
    
    inline int rd(){
        int x=0,f=1;char c=' ';
        while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
        while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    
    int n,limit,lim,f[maxn],g[maxn],a[maxn],b[maxn],rev[maxn];
    
    inline int qpow(int x,int k){
        int ret=1;
        while(k){
            if(k&1) ret=1LL*ret*x%mod;
            x=1LL*x*x%mod; k>>=1;
        } return ret%mod;
    }
    
    inline void NTT(int *F,int type){
        for(int i=0;i<limit;i++)
            if(i<rev[i]) swap(F[i],F[rev[i]]);
        for(int mid=1;mid<limit;mid<<=1){
            int Wn=qpow(3,type==1?(mod-1)/(mid<<1):(mod-1-(mod-1)/(mid<<1)));
            for(int r=mid<<1,j=0;j<limit;j+=r){
                int w=1;
                for(int k=0;k<mid;k++,w=1LL*w*Wn%mod){
                    int x=F[j+k],y=1LL*w*F[j+mid+k]%mod;
                    F[j+k]=(x+y)%mod,F[j+mid+k]=(x-y+mod)%mod;
                }
            }
        }
        if(type==-1){
            int inv=qpow(limit,mod-2);
            for(int i=0;i<limit;i++) F[i]=1LL*F[i]*inv%mod;
        }
    }
    
    inline void work(int *a,int *b){
        NTT(a,1); NTT(b,1);
        for(int i=0;i<limit;i++) a[i]=1LL*a[i]*b[i]%mod;
        NTT(a,-1);
    }
    
    void cdqFFT(int l,int r){
        if(l==r) return;
        int mid=(l+r)>>1,len=r-l-1;
        cdqFFT(l,mid);
        limit=1,lim=0;
        while(limit<=len) limit<<=1,++lim;
        for(int i=0;i<limit;i++)
            rev[i]=(rev[i>>1]>>1)|((i&1)<<(lim-1)),a[i]=b[i]=0;
        for(int i=l;i<=mid;i++) a[i-l]=f[i];
        for(int i=1;i<=r-l;i++) b[i-1]=g[i];
        work(a,b);
        for(int i=mid+1;i<=r;i++) f[i]=(f[i]+a[i-l-1]%mod)%mod;
        cdqFFT(mid+1,r);
    }
    
    int main(){
        n=rd(); f[0]=1;
        for(int i=1;i<n;i++) g[i]=rd();
        cdqFFT(0,n-1);
        for(int i=0;i<n;i++) printf("%d ",f[i]);
        return 0;
    }
    
  • 相关阅读:
    【转】Foreach用法
    【转】PB实现在通知区域添加图标
    手动清理SQLSERVER的日志文件
    2012腾讯实习笔试
    触控(捕鱼达人)笔试
    C和指针第五章操作符和表达式
    浮点数的存储
    C和指针第三章数据
    动态规划
    有关海量数据处理
  • 原文地址:https://www.cnblogs.com/yesuweiYYYY/p/15580260.html
Copyright © 2020-2023  润新知