zoukankan      html  css  js  c++  java
  • BZOJ2194:快速傅立叶之二(FFT)

    Description

    请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

    Input

    第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i < N)。

    Output

    输出N行,每行一个整数,第i行输出C[i-1]。

    Sample Input

    5
    3 1
    2 4
    1 1
    2 4
    1 4

    Sample Output

    24
    12
    10
    6
    1

    Solution

    QvQ我FFT也就能打个板子了
    对FFT的运用还是不够到位,理解也只是仅仅停留在表面的地方
    很多细节处以及证明并没有非常理解
    啥时候数学底子够了再回来重新补FFT的证明什么奇奇怪怪的东西吧
    反正学长告诉我我会打板子会用就好了
     
    首先做这个题之前我还不知道FFT式子的基本形式(逃
     

    像这样下标和一定的式子就能用FFT进行优化了

    下方公式转自https://blog.csdn.net/ycdfhhc/article/details/50636751

    因为我不会markdown

    一开始我们发现初始式子并不是FFT的形式没法搞

    然后我们就将B数组翻转过来,然后发现下标和一定了……

    然后把式子用另一个D表示出来,然后就可以FFT了……

    答案C(0~n-1)对应D(n-1,n+n-2)

    快二轮了感觉没啥希望

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #define N (400000+100)
     6 using namespace std;
     7 
     8 double pi=acos(-1.0);
     9 int n,fn,l,r[N];
    10 struct complex
    11 {
    12     double x,y;
    13     complex (double xx=0,double yy=0)
    14     {
    15         x=xx; y=yy;
    16     }
    17 }a[N],b[N];
    18 
    19 complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
    20 complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
    21 complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
    22 complex operator / (complex a,double b){return complex(a.x/b,a.y/b);}
    23 
    24 void FFT(int n,complex *a,int opt)
    25 {
    26     for (int i=0; i<n; ++i)
    27         if (i<r[i])
    28             swap(a[i],a[r[i]]);
    29     for (int k=1; k<n; k<<=1)
    30     {
    31         complex wn=complex(cos(pi/k),opt*sin(pi/k));
    32         for (int i=0; i<n; i+=(k<<1))
    33         {
    34             complex w=complex(1,0);
    35             for (int j=0; j<k; ++j,w=w*wn)
    36             {
    37                 complex x=a[i+j], y=w*a[i+j+k];
    38                 a[i+j]=x+y; a[i+j+k]=x-y;
    39             }
    40         }
    41     }
    42     if (opt==-1) for (int i=0; i<n; ++i) a[i]=a[i]/n;
    43 }
    44 
    45 int main()
    46 {
    47     scanf("%d",&n); n--;
    48     for (int i=0; i<=n; ++i)
    49         scanf("%lf%lf",&a[i].x,&b[n-i].x);
    50     fn=1;
    51     while (fn<=n+n) fn<<=1, l++;
    52     for (int i=0; i<fn; ++i)
    53         r[i]=(r[i>>1]>>1) | ((i&1)<<(l-1));
    54     FFT(fn,a,1); FFT(fn,b,1);
    55     for (int i=0; i<=fn; ++i)
    56         a[i]=a[i]*b[i];
    57     FFT(fn,a,-1);
    58     for (int i=n; i<=n+n; ++i)
    59         printf("%d
    ",(int)(a[i].x+0.5));
    60 }
  • 相关阅读:
    javax.xml.ws.WebServiceException: Provider com.sun.xml.ws.spi.ProviderImpl not found
    注意资源利用 不然导致资源消耗会很严重
    E212: 不能以写入模式打开 linux
    安装db2 提示不是有效的win32应用程序?
    对苹果“五仁”编程语言Swift的简单分析
    Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
    Oracle 学习笔记 14 -- 集合操作和高级子查询
    PHP的curl库代码使用
    AWS OpsWorks新增Amazon RDS支持
    最短编辑距离算法
  • 原文地址:https://www.cnblogs.com/refun/p/8823616.html
Copyright © 2011-2022 走看看