• hdu5730


    以前没写过这类题目

    dp方程不难得到 f[i]=∑ f[j]*a[i-j]

    这是卷积的形式,考虑用fft优化

    虽然f[i]之前的值是未确定的,但是这里可以算贡献,用分治即可

    具体的对于[l,r],先计算[l,mid]的f[],再计算f[l..mid]对f[mid+1..r]的贡献,最后计算f[mid+1..r]的值

     1 #include<bits/stdc++.h>
     2 #define pi acos(-1)
     3 #define N 262150
     4 using namespace std;
     5 typedef complex<double> E;
     6 
     7 const int mo=313;
     8 E ta[N],tb[N];
     9 int f[N],a[N],r[N],n;
    10 void fft(E *a,int n,int f)
    11 {
    12     for (int i=0; i<n; i++)
    13         if (i<r[i]) swap(a[i],a[r[i]]);
    14     for (int i=1; i<n; i<<=1)
    15     {
    16         E p(cos(pi/i),f*sin(pi/i));
    17         for (int j=0; j<n; j+=i<<1)
    18         {
    19             E w(1,0);
    20             for (int k=0; k<i; k++)
    21             {
    22                 E u=a[j+k],v=w*a[j+k+i];
    23                 a[j+k]=u+v;
    24                 a[j+k+i]=u-v;
    25                 w*=p;
    26             }
    27         }
    28     }
    29 }
    30 
    31 void work(int h,int t)
    32 {
    33     int m=t-h+1,mid=(h+t)>>1;
    34     int n,l=0;
    35     for (n=1; n<=m; n<<=1) l++;
    36     for (int i=0; i<n; i++)
    37     {
    38         r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    39         ta[i]=tb[i]=0;
    40     }
    41     for (int i=h; i<=mid; i++) ta[i-h]=f[i];
    42     for (int i=1; i<=m; i++) tb[i]=a[i];
    43     fft(ta,n,1); fft(tb,n,1);
    44     for (int i=0; i<=n; i++) ta[i]*=tb[i];
    45     fft(ta,n,-1);
    46     for (int i=mid+1; i<=t; i++)
    47         f[i]=(f[i]+(int)(ta[i-h].real()/n+0.5))%mo;
    48 }
    49 
    50 void solve(int l,int r)
    51 {
    52     if (l==r) return;
    53     int m=(l+r)>>1;
    54     solve(l,m);
    55     work(l,r);
    56     solve(m+1,r);
    57 }
    58 
    59 int main()
    60 {
    61     scanf("%d",&n);
    62     while (n)
    63     {
    64         for (int i=1; i<=n; i++)
    65         {
    66             scanf("%d",&a[i]);
    67             a[i]%=mo;
    68         }
    69         memset(f,0,sizeof(f));
    70         f[0]=1;
    71         solve(0,n);
    72         printf("%d
    ",f[n]);
    73         scanf("%d",&n);
    74     }
    75 }
    View Code
  • 相关阅读:
    软考过后
    最近
    软考复习初体验
    再看提高班
    C语言深入学习系列 字节对齐&内存管理
    C++ 阶段一(已完成)
    小弟,开博学习了!!
    [学习心得] 我总结的进制转换
    《深入浅出设计模式》一书学习(.net版—简单工厂)
    安装mysql 获得 mysql.h 建立C接口
  • 原文地址:https://www.cnblogs.com/phile/p/6566142.html
Copyright © 2020-2023  润新知