Fast Fourier Transform

来源:互联网 发布:手机怎样在淘宝买东西 编辑:程序博客网 时间:2024/06/10 05:33

c++复数类太慢了。。。于是就自己写了一个。。。、
FFT是很有意思的算法,可以尝试自己去写写。

提交地址:http://uoj.ac/problem/34

本记录:http://uoj.ac/submission/13994



FFT流程 :

  • A>a
  • B>b
  • ab=c
  • c>C

*大写字母表示系数表示法,小写字母表示点值表示法

时间复杂度:O(Nlog2N), 具体实现见《算法导论》



#include<map>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<iostream>#include<algorithm>const int MAXN = 1e5+5,MAXM = 1e5+5;const double pi = acos(-1);struct complex{double x,yi; complex(double x = 0,double yi = 0):x(x),yi(yi){}};complex operator + (const complex &a,const complex &b){return complex(a.x + b.x,a.yi + b.yi);}complex operator - (const complex &a,const complex &b){return complex(a.x - b.x,a.yi - b.yi);}complex operator * (const complex &a,const complex &b){return complex(a.x*b.x - a.yi*b.yi , a.x*b.yi + a.yi*b.x);}complex operator / (const complex &a,const double &b) {return complex(a.x/b,a.yi/b);}void FFT(complex *X,int n,int flag){    for(int i = 0; i < n; i++)    {        int p = 0, t = i;        for(int j = 1; j < n; j <<= 1)          p <<= 1, p |= (t&1), t >>= 1;        if(i < p) std::swap(X[i], X[p]);    }    for(int m = 2; m <= n; m <<= 1)    {        complex wm = complex(cos((double)2*pi*flag/m), sin((double)2*pi*flag/m));        for(int i = 0 ; i < n; i += m)        {             complex wk = complex(1, 0);             for(int j = 0; j < (m>>1); wk = wk*wm, j++)            {                complex u = X[i+j], t = wk*X[i+j+(m>>1)];                X[i+j] = u + t, X[i+j+(m>>1)] = u - t;            }        }    }    if(flag == -1) for(int i = 0; i < n; i++) X[i] = X[i]/n;}int main(){    int l, N , n , m;    static complex A[MAXN<<2] , B[MAXM<<2], C[(MAXN+MAXM)<<1];#ifndef ONLINE_JUDGE    freopen("FFT.in","r",stdin);    freopen("FFT.out","w",stdout);#endif    std::cin >> n >> m;     l = n + m + 1, N = 1;     while(N < l) N <<=1;    for(int i = 0; i <= n; i++)scanf("%lf",&A[i].x);    for(int i = 0; i <= m; i++)scanf("%lf",&B[i].x);    FFT(A, N, 1);FFT(B, N, 1);    for(int i = 0; i < N; i++) C[i] = A[i]*B[i];    FFT(C, N, -1);    for(int i = 0; i < l; i++) printf("%d ", (int)(C[i].x+0.5));#ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);#endif    return 0;}
0 0