zoukankan      html  css  js  c++  java
  • 洛谷 P4721 分治FFT

    因为要求出fj要先求出fi(i<j),且式子是和式,故fi对fj的影响是独立的,考虑运用CDQ分治的思想。

    为了代码的高效优美简洁,有以下几个具体实现:

    • 分治过程中用到STL函数(左闭右开),且区间长为2的幂,为方便,l,r,表示的应是区间[l,r)。
    • 在区间[l,r)中,求出区间[l,mid)对区间[mid,r)的影响,而非[mid,Max)。
    • 对于数组r,应在计算不同长度的卷积前重新计算(因为这个调了1小时)。

    代码用NTT实现:

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    using namespace std;
    const int N=4e5+3,P=998244353,G=3,Gi=332748118;
    IL int in(){
        char c;int f=1;
        while((c=getchar())<'0'||c>'9')
          if(c=='-') f=-1;
        int x=c-'0';
        while((c=getchar())>='0'&&c<='9')
          x=x*10+c-'0';
        return x*f;
    }
    LL g[N],f[N],a[N],b[N];
    int n,m,r[N],Max=1,cnt;
    IL LL ksm(LL a,LL b){
        LL c=1;
        while(b){
            if(b&1) c=c*a%P;
            a=a*a%P,b>>=1;
        }
        return c;
    }
    IL void get(int len){for(int i=0;i<len;++i) r[i]=(r[i>>1]>>1)|((i&1)*len>>1);}
    IL void FFT(LL *a,int len,int op){
        for(int i=0;i<len;++i) if(i<r[i]) swap(a[i],a[r[i]]);
        for(int i=1;i<len;i<<=1){
            LL wn=ksm(~op?G:Gi,(P-1)/(i<<1));
            for(int j=0,l=i<<1;j<len;j+=l){
                LL w=1;
                for(int k=0;k<i;++k,w=w*wn%P){
                    LL x=a[j+k],y=w*a[j+i+k]%P;
                    a[j+k]=(x+y)%P,a[j+i+k]=(x-y+P)%P;
                }
            }
        }
    }
    void solve(int l,int r){
        if(l+1==r) return;
        int mid=l+r>>1,m=(r-l)>>1;
        solve(l,mid);
        LL inv=ksm(r-l,P-2);get(r-l);
        memset(a+m,0,8*m),memcpy(a,f+l,8*m),memcpy(b,g,8*(r-l));
        FFT(a,r-l,1),FFT(b,r-l,1);
        for(int i=0;i<r-l;++i) a[i]=a[i]*b[i]%P;
        FFT(a,r-l,-1);
        for(int i=m;i<r-l;++i) a[i]=a[i]*inv%P;
        for(int i=m;i<r-l;++i) f[l+i]=(f[l+i]+a[i])%P;
        solve(mid,r);
    }
    int main()
    {
        n=in(),f[0]=1;
        for(int i=1;i<n;++i) g[i]=in();
        while(Max<n) Max<<=1,++cnt;
        solve(0,Max);
        for(int i=0;i<n;++i) printf("%lld ",f[i]);
        return 0;
    }
  • 相关阅读:
    linux命令学习笔记(53):route命令
    linux命令学习笔记(52):ifconfig命令
    linux命令学习笔记(51):lsof命令
    linux命令学习笔记(47):iostat命令
    图文并解Word插入修改删除批注
    两步教你生成文档目录
    UML 类图介绍
    win7电脑磁盘文件以分组方式展现解决方案
    jQuery插件开发中$.extend和$.fn.extend辨析
    jquery.fn.extend与jquery.extend
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/12070311.html
Copyright © 2011-2022 走看看