首页 > 其他 > 详细

快速傅立叶变换(FFT)及其应用

时间:2018-09-02 16:47:10      阅读:148      评论:0      收藏:0      [点我收藏+]

在信息学竞赛中FFT只有一个用处那就是加速多项式的乘法

多项式乘法原本的时间复杂度是O(n^2)的,然后经过FFT之后可以优化为O(nlogn)

FFT就是将系数表示法转化成点值表示法相乘,再由点值表示法转化为系数表示法的过程

一个典型的例题是BZOJ2194,求卷积?

 1 #include<complex>
 2 #include<cmath>
 3 #include<cstdio>
 4 #define pi acos(-1)
 5 using namespace std;
 6 const int maxn=131072;
 7 int n,m,L;
 8 int R[maxn];
 9 complex<double> a[maxn],b[maxn];
10 int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
14     while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
15     return x*f;
16 }
17 void fft(complex<double> *a,int f)
18 {
19     for(int i=0;i<n;i++) if(i<R[i]) swap(a[i],a[R[i]]);
20     for(int i=1;i<n;i<<=1)
21     {
22         complex<double> wn(cos(pi/i),f*sin(pi/i));
23         for(int j=0;j<n;j+=(i<<1))
24         {
25             complex<double> w(1,0);
26             for(int k=0;k<i;k++,w*=wn)
27             {
28                 complex<double> x=a[j+k],y=w*a[j+k+i];
29                 a[j+k]=x+y;a[j+k+i]=x-y;
30             }
31         }
32     }
33     if(f==-1) for(int i=0;i<n;i++) a[i]/=n;
34 }
35 int main()
36 {
37     scanf("%d",&n);
38     n--;
39     for(int i=0;i<=n;i++)
40     {
41         a[i]=read();
42         b[n-i]=read();
43     }
44     m=2*n;
45     for(n=1;n<=m;n<<=1) L++;
46     for(int i=0;i<n;i++) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
47     fft(a,1);fft(b,1);
48     for(int i=0;i<=n;i++) a[i]*=b[i];
49     fft(a,-1);
50     for(int i=m/2;i<=m;i++) printf("%d\n",(int)(a[i].real()+0.1));
51     return 0;
52 }

现在我所知道的就是FFT和多项式、复数和单位根有关系

别的等日后再补吧。。

快速傅立叶变换(FFT)及其应用

原文:https://www.cnblogs.com/aininot260/p/9574194.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!