快速傅里叶变换(FFT) 学习笔记
快速傅里叶变换(FFT) 学习笔记
简介:
卷积是形如
而快速傅里叶变换(FFT)用于在
对于一个
单位根
先考虑求点值。我们肯定不能暴力选择点去代入求值,这样的时间复杂度是
于是我们在复数域找到了单位根,它是在复平面上的单位圆上的点,表示为
对于最后一条,我们可以将
对于一个
先将多项式
再分别将
发现上下两式只有后面一项的符号不同,所以如果我们求出了
但是此时我们又有一个问题:如果某个
tr[i]=(tr[i>>1]>>1)|(i&1)?limit>>1:0
求多项式
通过上面的步骤,我们已经将
设点值构成的序列为
然后可以得到以下结论:
这个式子的证明就是将上面的式子代入。此时我们发现,这个式子和我们求点值的式子十分相似,只是在单位根上有点区别。我们可以发现,在单位圆上,
Code
#include<cstdio> #include<cmath> using namespace std; const int N=3e6+5;const double PI=6.28318530717958646; struct Date{ double x,y; Date operator*(Date v) { Date res;res.x=x*v.x-y*v.y;res.y=x*v.y+y*v.x;return res; }; Date operator+(Date v) { Date res;res.x=x+v.x;res.y=y+v.y;return res; }; Date operator-(Date v) { Date res;res.x=x-v.x;res.y=y-v.y;return res; }; };Date f[N],g[N],w[N]; int tr[N],n,m; void swap(double &x,double &y) { double t=x;x=y;y=t; } void FFT(int flag) { int i,j,len;Date t; w[0].x=1;w[0].y=0; w[1].x=cos(PI/n);w[1].y=sin(PI/n)*flag; for(i=1;i<n;i++) w[i]=w[i-1]*w[1]; for(i=0;i<n;i++) { if(i<tr[i]) { swap(f[i].x,f[tr[i]].x);swap(f[i].y,f[tr[i]].y); } } for(len=1;len<n;len=len<<1) { for(i=0;i<n;i+=2*len) { for(j=0;j<len;j++) { t=f[i+j+len]*w[n/len/2*j]; f[i+j+len]=f[i+j]-t;f[i+j]=f[i+j]+t; } } } } int main() { int i,h,len; scanf("%d%d",&n,&m); for(i=0;i<=n;i++) scanf("%lf",&f[i].x); for(i=0;i<=m;i++) scanf("%lf",&g[i].x); h=0;len=n+m; while((1<<h)<n+m+1) h++; n=1<<h; for(i=0;i<n;i++) tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0); FFT(1); for(i=0;i<n;i++) { swap(f[i].x,g[i].x);swap(f[i].y,g[i].y); } FFT(1); for(i=0;i<n;i++) f[i]=f[i]*g[i]; FFT(-1); for(i=0;i<=len;i++) printf("%d ",int(f[i].x/n+0.49)); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南