FFT(快速傅里叶变换)

前置知识

\(1.复数\)

\(2.单位根\)

\(3.循环结构\)

\(4.C++\)

1.复数

  • \(定义:形如a+bi的数,其中i^2=-1\)

  • \(计算:1.(a+bi)+(c+di)=(a+c)+(b+d)i\)

    \(\ \ \ \ \ \ \ \ \ \ \ 2.(a+bi)-(c+di)=(a-c)+(b-d)i\)

    \(\ \ \ \ \ \ \ \ \ \ \ 3.(a+bi)(c+di)=(ac-bd)+(ad+bc)i\)

  • \(向量表示法\)

    \(用x表示实部(没有i的部分),用y表示虚部(i前的系数)\)

    \(性质1.复数乘法满足向量模角相加\)

    \(证明:arctan(\frac{a}{b})+arctan(\frac{c}{d})=arctan(\frac{\frac{a}{b}+\frac{c}{d}}{1-\frac{ac}{bd}})=arctan(\frac{ad+bc}{bd-ac})\)

    \(是不是巨简单!\)

2.单位根

  • \(定义:n次单位根是n次幂为1的复数。它们位于复平面的单位圆上,\)

    \(构成正n边形的顶点,其中一个顶点是1。\)

  • \(显然,\omega_n^0=\omega_n^n=1,\omega_n=(cos(\frac{2\pi}{n}),sin(\frac{2\pi}{n})),n个复数为\omega_n^1,\omega_n^2...\omega_n^n\)

  • \(性质:\omega_{n}^k=\omega_{2n}^{2k}\)

正题

\(令A(x)=a_0+a_1x^1...a_nx^n\)

\(则A(x)=(a_0+a_2x^2...a_{2\lfloor\frac{n}{2}\rfloor}x^{2\lfloor\frac{n}{2}\rfloor})+(a_1x+a_3x^3...a_{2\lfloor\frac{n}{2}\rfloor+1}x^{2\lfloor\frac{n}{2}\rfloor+1}),令左边的为A_1(x^2),右边的为xA_2(x^2),A(x)=A_1(x^2)+xA_2(x^2)\)

\(将\omega_n^k(k<\frac{n}{2})带入得\)

\(A(\omega_n^k)=A_1(\omega_n^{2k})+\omega_n^kA_2(\omega_n^{2k})\)

\(将\omega_n^{k+\frac{n}{2}}带入得\)

\(A(\omega_n^k)=A_1(\omega_n^{2k})-\omega_n^kA_2(\omega_n^{2k})\)

\(我们发现2式只有系数不同,所以可以在k\in[0,\frac{n}{2}-1]时顺便把k\in[\frac{n}{2},n-1]计算出来,就可以实现以下时间\)

\[ T(n)=\left\{
\begin{array}{rcl}
2T(\frac{n}{2})+n&& {1<n}\\
1&& {n=1}
\end{array} \right. \]

\(时间复杂度为O(nlog_2n)\)


细节

  1. 为使序列长度为\(2^m\),把不足位补0

  2. 把下标奇偶分类后的位置其实就是2进制下的反转,所以可以通过迭代(非递归)实现,实际效率也是递归版的\(1.5\)~\(2\)倍

\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
# define read read1<int>()
# define Type template<typename T>
Type inline T read1(){
T n=0;
char k;
bool fl=0;
do (k=getchar())=='-'&&(fl=1);while('9'<k||k<'0');
while(47<k&&k<58)n=(n<<3)+(n<<1)+(k^48),k=getchar();
return fl?-n:n;
}
# define f(i,l,r) for(int i=(l);i<=(r);++i)
# define fre(k) freopen(k".in","r",stdin);freopen(k".ans","w",stdout)
const double PI=acos(-1);
class complex{
public:
double x,y;
complex(){x=y=0;}
complex(double _x,double _y):x(_x),y(_y){}
complex operator * (complex b){return complex(x*b.x-y*b.y,x*b.y+y*b.x);}
complex operator + (complex b){return complex(x+b.x,y+b.y);}
complex operator - (complex b){return complex(x-b.x,y-b.y);}
complex operator * (double u){return complex(x*u,y*u);}
complex& operator *= (complex b){return *this=*this*b;}
complex& operator += (complex b){return *this=*this+b;}
complex& operator -= (complex b){return *this=*this-b;}
};
class Array{
private:
vector<int>a;
public:
Array(){}
void push(int n){a.push_back(n);}
Array(int* l,int* r){while(l!=r)push(*l),++l;}
int size(){return a.size();}
int& operator [] (const int x){return a[x];}
};
void FFT(const int len,vector<complex>&a,const int Ty,int *r=NULL){
if(!r){
r=new int[len];
r[0]=0;int L=log2(len);
f(i,0,len-1){
r[i]=(r[i>>1]>>1)|((i&1)<<L-1);
if(i<r[i])swap(a[i],a[r[i]]);
}
}
for(int i=1;i<len;i<<=1){
complex T(cos(PI/i),Ty*sin(PI/i));
for(int W=i<<1,j=0;j<len;j+=W){
complex n(1,0);
for(int k=0;k<i;++k,n*=T){
complex x(a[j+k]),y(n*a[i+j+k]);
a[j+k]=x+y;
a[i+j+k]=x-y;
}
}
}
}
Array operator * (Array x,Array y){
int n=x.size()-1,m=y.size()-1;
int limit=1;
while(limit<=n+m)limit<<=1;
vector<complex>_x(limit+1),_y(limit+1);
Array ans;
f(i,0,n)_x[i]=complex(x[i],0);
f(i,0,m)_y[i]=complex(y[i],0);
FFT(limit,_x,1);
FFT(limit,_y,1);
f(i,0,limit)_x[i]*=_y[i];
FFT(limit,_x,-1);
f(i,0,n+m)ans.push((int)(_x[i].x/limit+0.5));
return ans;
}
void into(int n,Array &x){
f(i,0,n)x.push(read);
}
Array x,y,ans;
int main(){
int n=read,m=read;
into(n,x),into(m,y);
ans=x*y;
f(i,0,n+m)printf("%d ",ans[i]);
return 0;
}

FFT(快速傅里叶变换)的更多相关文章

  1. FFT 快速傅里叶变换 学习笔记

    FFT 快速傅里叶变换 前言 lmc,ikka,attack等众多大佬都没教会的我终于要自己填坑了. 又是机房里最后一个学fft的人 早背过圆周率50位填坑了 用处 多项式乘法 卷积 \(g(x)=a ...

  2. CQOI2018 九连环 打表找规律 fft快速傅里叶变换

    题面: CQOI2018九连环 分析: 个人认为这道题没有什么价值,纯粹是为了考算法而考算法. 对于小数据我们可以直接爆搜打表,打表出来我们可以观察规律. f[1~10]: 1 2 5 10 21 4 ...

  3. 「学习笔记」FFT 快速傅里叶变换

    目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...

  4. FFT —— 快速傅里叶变换

    问题: 已知A[], B[], 求C[],使: 定义C是A,B的卷积,例如多项式乘法等. 朴素做法是按照定义枚举i和j,但这样时间复杂度是O(n2). 能不能使时间复杂度降下来呢? 点值表示法: 我们 ...

  5. [C++] 频谱图中 FFT快速傅里叶变换C++实现

    在项目中,需要画波形频谱图,因此进行查找,不是很懂相关知识,下列代码主要是针对这篇文章. http://blog.csdn.net/xcgspring/article/details/4749075 ...

  6. matlab中fft快速傅里叶变换

    视频来源:https://www.bilibili.com/video/av51932171?t=628. 博文来源:https://ww2.mathworks.cn/help/matlab/ref/ ...

  7. FFT快速傅里叶变换算法

    1.FFT算法概要: FFT(Fast Fourier Transformation)是离散傅氏变换(DFT)的快速算法.即为快速傅氏变换.它是根据离散傅氏变换的奇.偶.虚.实等特性,对离散傅立叶变换 ...

  8. FFT快速傅里叶变换

    FFT太玄幻了,不过我要先膜拜HQM,实在太强了 1.多项式 1)多项式的定义 在数学中,由若干个单项式相加组成的代数式叫做多项式.多项式中的每个单项式叫做多项式的项,这些单项式中的最高项次数,就是这 ...

  9. [学习笔记]FFT——快速傅里叶变换

    大力推荐博客: 傅里叶变换(FFT)学习笔记 一.多项式乘法: 我们要明白的是: FFT利用分治,处理多项式乘法,达到O(nlogn)的复杂度.(虽然常数大) FFT=DFT+IDFT DFT: 本质 ...

  10. FFT(快速傅里叶变换)

    学习了FFT用来求多项式的乘法,看了算导上的介绍,上面讲的非常明白,概括一下FFT的原理就是,我们在计算多项式的乘法时,如果暴力模拟的话是n^2 复杂度的,就像小学学的竖式乘法一样,比如一个n位数乘上 ...

随机推荐

  1. 【机器学习笔记】ID3构建决策树

    好多算法之类的,看理论描述,让人似懂非懂,代码走一走,现象就了然了. 引: from sklearn import tree names = ['size', 'scale', 'fruit', 'b ...

  2. 面试前必须要知道的21道Redis面试题

    1.使用redis有哪些好处? 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) 支持丰富数据类型,支持string,list,set,so ...

  3. 在vue项目中通过iframe引入jquery项目

    最近公司因为原来的jq框架存在的问题太多,所以要进行主题框架的重新搭建,我使用的vue进行的主题框架的重新搭建,但是原来的页面已经完成很多了,而且都是使用的jquery进行开发的 在vue中引入jqu ...

  4. 转 Fortofy扫描漏洞解决方案2

    Fortify漏洞之Portability Flaw: File Separator 和 Poor Error Handling: Return Inside Finally   继续对Fortify ...

  5. Python 报错 MySQLdb._exceptions.OperationalError: (2059, )

    Python连接MySQL数据时:报错提示MySQLdb._exceptions.OperationalError: (2059, <NULL>). Python包: mysqlclien ...

  6. 设置VMware中Kali 共享文件夹

    (软件环境: Vmware Workstation 15.5 Pro , Kali Linux2019.3) 1. VMware设置共享目录 2. 安装VMware-Tools 命令: apt-get ...

  7. 源码详解Pytorch的state_dict和load_state_dict

    在 Pytorch 中一种模型保存和加载的方式如下: # save torch.save(model.state_dict(), PATH) # load model = MyModel(*args, ...

  8. JS高阶---进程与线程

    [大纲] 二级大纲: 三级大纲: [主体] (1)进程process 如下所示,两者内存空间相互独立 (2)线程thread (3)图解 注意:有的程序是多进程的,有的时单进程的 (4)单线程与多线程 ...

  9. 第七周scrum会议

    本周会议地点依旧 会议照片: 本周内容: 讨论了进行中的难点 我们正在分析图书馆首页的网页结构以及各种跳转的请求以及链接,为爬虫的实现奠定基础. flask框架我们也遇到了很多问题,正在进行官方文档的 ...

  10. Nginx的代理配置(六)

    一.正向代理 1. 指令说明 (1) resolver 这个用于设置DNS服务器的ip .DNS服务器的主要工作是进行域名解析,将域名映射为对应IP地址. 语法:resolver address .. ...