zoukankan      html  css  js  c++  java
  • HDU

    不难想到DP方程f[i]=sigema(0,i-1)j f[j]*a[i-j]

    这是一个卷积,然而并不能直接卷

    上分治fft

    注意ntt用不了。。。313=2^3*3*13+1

    推的我心态都崩了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    typedef long double LD;
    const int _=1e2;
    const int maxn=1e5+_;
    const int fbin=((1<<17)<<1)+_;
    const int mod=313;
    
    const double pi=acos(-1.0);
    struct complex
    {
        LD r,i;
        complex(){} complex(double R,double I){r=R,i=I;}
        friend complex operator +(complex c1,complex c2){return complex(c1.r+c2.r,c1.i+c2.i);}
        friend complex operator -(complex c1,complex c2){return complex(c1.r-c2.r,c1.i-c2.i);}
        friend complex operator *(complex c1,complex c2){return complex(c1.r*c2.r-c1.i*c2.i,c1.r*c2.i+c2.r*c1.i);}
    }A[fbin],B[fbin]; int Re[fbin],h[fbin];
    void FFT(complex *a,int n,int op)
    {
        for(int i=0;i<n;i++)
            if(i<Re[i])swap(a[i],a[Re[i]]);
         
        for(int i=1;i<n;i<<=1)
        {
            complex wn(cos(pi/i),sin(op*pi/i));
            for(int j=0;j<n;j+=(i<<1))
            {
                complex w(1,0);
                for(int k=0;k<i;k++,w=w*wn)
                {
                    complex t1=a[j+k],t2=a[j+k+i];
                    a[j+k]=t1+w*t2;
                    a[j+k+i]=t1-w*t2;
                }
            }
        }
        if(op==-1)
            for(int i=0;i<n;i++)
                h[i]=(LL)(A[i].r/n+0.5)%mod,a[i].i=0;
    }
    
    int a[maxn],f[maxn];
    void solve(int l1,int r1,int l2,int r2)
    {
        int d1=(r1-l1+1),d2=(r2-l2+1);
        
        int n,m,L;
        m=d1+d2-1;for(n=1,L=0;n<m;n*=2,L++);
        for(int i=0;i<n;i++)Re[i]=(Re[i>>1]>>1)|((i&1)<<(L-1));
        for(int i=0;i<n;i++)A[i].r=A[i].i=B[i].r=B[i].i=0;
        
        for(int i=0;i<d1;i++)A[i].r=f[i+l1];
        for(int i=0;i<d2;i++)B[i].r=a[i+l2];
        FFT(A,n,1),FFT(B,n,1);
        for(int i=0;i<n;i++)A[i]=A[i]*B[i];
        FFT(A,n,-1);
    }
    
    void cdq(int l,int r)
    {
        if(l==r)return ;
        int mid=(l+r)/2;
        cdq(l,mid);
        solve(l,mid,1,r-l);
        for(int i=mid+1,j=mid-l;i<=r;i++,j++)
            f[i]=(f[i]+h[j])%mod;
        cdq(mid+1,r);
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)break;
            for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]%=mod;
            memset(f,0,sizeof(f));
            f[0]=1;
            cdq(0,n);
    //        for(int i=1;i<n;i++)printf("%d ",f[i]);
            printf("%d
    ",f[n]);
        }
        
        return 0;
    }
  • 相关阅读:
    如何在获取celery中的任务执行情况
    python flask接口开发和入参的三种方式args、values、json
    python3 redis数据库写入方法和json格式的坑
    python3 封装好的时间戳转换函数,可直接使用
    python3 *args 、 **args 在函数定义和调用中的应用
    python中剔除字典重复项,可以使用集合(set)。
    python3 文件读写操作中的文件指针seek()使用
    jmeter数据库连接配置
    Python自动化培训第一周学习总结
    jmeter分布式压测
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10556322.html
Copyright © 2011-2022 走看看