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;
    }
  • 相关阅读:
    JQuery实现Ajax应用
    访问本地json文件因跨域导致的问题
    python_控制台输出带颜色的文字方法
    查询数据量大时,你会选择关联表查询还是循环中依个查询? up
    自己动手写SQL字符串分解函数Split up
    关于Access数据库执行Update语句后,不报错,但影响行数总是返回0的问题...... up
    TCP和UDP的区别
    Linxu系统下怎么安装vim编辑器
    网络编程 委托
    学习POS的数据包分析
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/12070311.html
Copyright © 2011-2022 走看看