【模板】FFT快速傅里叶变换

 1 struct Complex{
 2     double x, y;
 3     inline Complex(double xx=0, double yy=0){
 4         x=xx; y=yy;
 5     }
 6     inline Complex operator + (Complex a){
 7         return Complex(x+a.x, y+a.y);
 8     }
 9     inline Complex operator - (Complex a){
10         return Complex(x-a.x, y-a.y);
11     }
12     inline Complex operator * (Complex a){
13         return Complex(x*a.x-y*a.y, x*a.y+y*a.x);
14     }
15 }A[N], B[N];
16
17 int n, m, L;
18 int rev[N];
19
20 void FFT(Complex *a, int le, int ty){
21     for (int i=0; i<le; ++i)
22         if (i < rev[i]) swap(a[i], a[rev[i]]);
23     for (int i=1; i<le; i<<=1){
24         Complex wn=Complex(cos(pi/i), ty*sin(pi/i));
25         for (int j=0; j<le; j+=i<<1){
26             Complex w=Complex(1, 0), x, y;
27             for (int k=0; k<i; ++k, w=w*wn){
28                 x=a[j+k]; y=a[j+i+k]*w;
29                 a[j+k]=x+y; a[j+i+k]=x-y;
30             }
31         }
32     }
33 }
34
35 int main(){
36     scanf("%d%d", &n, &m); ++n; ++m;
37     for (L=1; L<n+m-1; L<<=1) continue;
38     for (int i=0; i<L; ++i){
39         rev[i]=rev[i>>1]>>1;
40         if (i&1) rev[i]|=L>>1;
41     }
42     for (int i=0, z; i<n; ++i) scanf("%d", &z), A[i].x=z;
43     for (int i=0, z; i<m; ++i) scanf("%d", &z), B[i].x=z;
44     FFT(A, L, 1);
45     FFT(B, L, 1);
46     for (int i=0; i<L; ++i) A[i]=A[i]*B[i];
47     FFT(A, L, -1);
48     for (int i=0; i<n+m-1; ++i) printf("%d ", (int)(A[i].x/L+0.5));
49
50     return 0;
51 }

原文地址:https://www.cnblogs.com/Dance-Of-Faith/p/8461382.html

时间: 2024-11-06 07:43:56

【模板】FFT快速傅里叶变换的相关文章

准零基础搞懂FFT快速傅里叶变换及其实现程序(二)

上一篇文章我们了解了DFT的原理,FFT是基于DFT的更适合计算机运算的算法,本文我们就正式开始学习FFT的原理. 首先我么先来宏观的看一下FFT.如果我们把整个FFT的算法看成一个黑盒子的话,那么它的输入就是时间波形信号,比如声音波形(横轴为时间,纵轴为振幅).外什么FFT要比DFT速度更快呢?下面(图1)解释了FFT和DFT的(对于计算机的)算法复杂度 图1 从上面的数学表达式可以看出,一个1024采样点的FFT比DFT块了102.4倍.如果傅里叶变换的数量级更大,FFT的速度优势会更明显.

FFT —— 快速傅里叶变换

问题: 已知A[], B[], 求C[],使: 定义C是A,B的卷积,例如多项式乘法等. 朴素做法是按照定义枚举i和j,但这样时间复杂度是O(n2). 能不能使时间复杂度降下来呢? 点值表示法: 我们把A,B,C看作表达式. 即: A(x)=a0 + a1* x + a2 * x2 +... 将A={(x1,A(x1)), (x2,A(x2)), (x3,A(x3))...}叫做A的点值表示法. 那么使用点值表示法做多项式乘法就很简单了:对应项相乘. 那么,如何将A和B转换成点值表示法,再将C转

【Delphi】如何在三轴加速器的频谱分析中使用FFT(快速傅里叶变换)算法

关于傅里叶变换的作用,网上说的太过学术化,且都在说原理,已经如何编码实现,可能很多人有个模糊影响,在人工智能,图像识别,运动分析,机器学习等中,频谱分析成为了必备的手段,可将离散信号量转换为数字信息进行归类分析. 今天这里将的不是如何实现,而是如何使用傅里叶变换 但频谱分析中,涉及到的信号处理知识对大部分软件开发的人来说,太过于晦涩难懂,傅里叶变换,拉普拉斯,卷积,模相,实数,虚数,复数,三角函数等等,已经能让软件工程师望而却步,造成懂知识的人无法开发,懂开发的人无法分析,而同时具备两种技能的人

FFT快速傅里叶变换

摘自:https://www.cnblogs.com/RabbitHu/p/FFT.html 快速傅里叶变换(FFT)是一种能在O(nlogn)O(nlog?n)的时间内将一个多项式转换成它的点值表示的算法. 点值表示:设A(x)是一个n−1次多项式,那么把n个不同的x代入,会得到n个y.这n对(x,y)唯一确定了该多项.由多项式可以求出其点值表示,而由点值表示也可以求出多项式. 设有两个n−1次多项式A(x)和B(x)),我们的目标是——把它们乘起来.普通的多项式乘法是O(n^2),但有趣的是

LG3803 「模板」快速傅里叶变换 FFT

问题描述 LG3803 题解 点我 \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; const int maxn=1350000; const double Pi=acos(-1); int n,m; struct CP{ CP(double X=0,double Y=0) {x=X,y=Y;} double x,y; CP operator + (CP const &a) const {return CP(

【bzoj2179】FFT快速傅里叶变换(优化高精度乘法)

#include<bits/stdc++.h> using namespace std; #define pi acos(-1) typedef complex<double> C; const int N=201100; int n,m,l,r[N],ans[N]; C a[N],b[N]; char s[N],t[N]; void fft(C *a,int f){ for(int i=0;i<n;++i) if(r[i]>i) swap(a[i],a[r[i]]);

【模板】快速傅里叶变换

uoj34 1 #include<bits/stdc++.h> 2 #define db double 3 using namespace std; 4 const int N=400010; 5 const db PI=acos(-1); 6 int n,m,tot,maxp,rev[N]; 7 struct Com{ 8 db real,image; 9 Com operator+(const Com& k)const{return (Com){real+k.real,image+

浅谈FFT(快速傅里叶变换)

本文主要简单写写自己学习FFT的经历以及一些自己的理解和想法. FFT的介绍以及入门就不赘述了,网上有许多相关的资料,入门的话推荐这篇博客:FFT(最详细最通俗的入门手册),里面介绍得很详细. 为什么要学习FFT呢?因为FFT能将多项式乘法的时间复杂度由朴素的$O(n^2)$降到$O(nlogn)$,这相当于能将任意形如$f[k]=\sum\limits _{i+j=k}f[i]*f[j]$的转移方程的计算在$O(nlogn)$的时间内完成.因此对于想要进阶dp的同学来说,FFT是必须掌握的技能

FFT 快速傅里叶变换

这个东西很神奇,看了半天网上的解释和课件,研究了很长时间,算是大概明白了它的原理. 话不多说先上图. 我们要求的h(x)=f(x)*g(x),f(x)=Σai*x^i,g(x)=Σbi*x^i. 朴素求复杂度是n2的,但一个x次多项式在平面上可以由x+1个点唯一插值表示,所以我们可以先用求出x+1个点(xi,f(xi))和(xi,g(xi)),再求出(xi,f(xi)*g(xi)),就可以反解出    h(x)的表达式. 那么我们需要在nlogn的时间内干完这两步,首先xi的取值需要特殊取,令x