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. 第一章 权限管理DEMO简介

    源代码GitHub:https://github.com/ZhaoRd/Zrd_0001_AuthorityManagement 1.系列介绍 工作已有五年之久,一直有想通过博客写点自己知道的,在博客 ...

  2. https抓包 Fiddler

    打开Fiddler https抓包 安装证书 查看证书 打开Windows程序certmgr.msc 查找Fiddler证书 查看Fiddler证书是否安装成功 测试连接 使用Google Chrom ...

  3. Spark(4)

    Spark Core官网学习回顾 Speed disk 10x memory 100x Easy code interactive shell Unified Stack Batch Streamin ...

  4. day09 作业

    简述定义函数的三种方式 空函数.无参函数.有参函数 简述函数的返回值 函数内部代码经过一系列的逻辑处理返回的结果 函数没有返回值,默认返回None 函数可以通过return返回出返回值 return可 ...

  5. adb 连接夜神和逍遥模拟器

    然后运行cmd命令,cd到夜神安装目录,执行命令 adb connect 127.0.0.1:62001 nox_adb.exe connect 127.0.0.1:62001 逍遥模拟器 adb c ...

  6. nodejs简单http日志存储

    nodejs实现简单http日志存储 /* 日志存储: 202.189.63.115 - - [31/Aug/2008:15:42:31 +0800] "GET / HTTP/1.1&quo ...

  7. [Python]使用生成器来简化代码

    原本只是大概知道生成器是什么,但一直不知道怎么用,或是什么情景下用,后来才发现: 在需要一边读数据一边处理任务时,如果直接为每个任务都写一个函数,那么读数据的部分就要在每个函数都重复一遍 直接将所有任 ...

  8. AssetBundleMaster_Introduce_EN

    This is an integrated solution for building AssetBundles and loading Assets. what it can do is about ...

  9. Socket-window通讯

    #define _WINSOCK_DEPRECATED_NO_WARNINGS #include<WINSOCK2.H> #include<STDIO.H> #include& ...

  10. Kubernetes 记一次网络请求分析

    查看pod,server root @ master ➜ ~ kubectl get po,svc -n irm-server -o wide NAME READY STATUS RESTARTS A ...