多项式

定义

形如\(A(x)=\sum_{i=0}^{n-1} a_i x^i\)的式子称为多项式。
我们把\(n\)称为该多项式的次数界。
显然,一个\(n-1\)次多项式的次数界为\(n\)。

运算法则

设\(A(x)\)和\(B(x)\)为多项式,且次数界分别为\(n\),\(m\)。则有:
\(A(x)=\sum_{i=0}^{n-1}a_i x^i\)
\(B(x)=\sum_{i=0}^{m-1}b_i x^i\)

他们遵循下面的常用运算法则:

\(A(x)+B(x)=\sum_{i=0}^{max(n-1,m-1)} (a_i+b_i)x^i\)
\(A(x)-B(x)=\sum_{i=0}^{max(n-1,m-1)} (a_i-b_i)x^i\)
\(A(x)B(x)=\sum_{k=0}^{n+m-2}\sum_{i=0}^{k}a_i b_{k-i} x^k\)

两个多项式的乘积称为他们的卷积。卷积也是一个多项式。
易证次数界分别为\(n\),\(m\)的多项式的卷积是一个次数界为\(n+m-1\)的多项式。
用定义计算卷积的复杂度为\(O(n^2)\)
使用快速傅里叶变换,可以使复杂度降为\(O(nlogn)\)

复数

代数形式

形如\(a+bi\)形式的数称为复数。其中\(i\)是\(\sqrt{-1}\)
我们可以使用平面上的点\((a,b)\)来描述一个复数。
复数的运算法则和向量相似。

三角形式

除了上文提到的代数形式,也有一种三角形式来表示复数。
如图所示。

我们知道复数\(a+bi\)对应着平面上的点\((a,b)\),也对应着复平面上的一个向量。
这个向量的长度叫做复数\(a+bi\)的模,记作\(|a+bi|\),通常用小写字母\(r\)表示。
这个向量与\(x\)正半轴有一个夹角,称为辐角,我们用希腊字母\(\theta\)表示。

显然有\(a=r\cos\theta\),\(b=r\sin\theta\)
把上式带入到代数表达式,可以得到\(a+bi=r\cos\theta+ir\sin\theta=r(\cos\theta+i\sin\theta)\)

定理:两复数相乘,模长相乘,辐角相加。
证明:
设\(z_1=r_1(\cos x+i\sin x)\),\(z_2=r_2(\cos y+i\sin y)\).
则\(z_1 z_2=r_1 r_2 [\cos x\cos y-\sin x\sin y+i(\cos x\sin y+\cos y\sin x)]=r_1 r_2[\cos(x+y)+i\sin(x+y)]\)

指数形式

欧拉公式:\(e^{i\theta}=\cos\theta+i\sin\theta\)
证明:
将\(e^x\),\(\sin x\),\(\cos x\)按照泰勒展开得到他们的泰勒级数:
\(e^x=1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+…\)
\(\cos x=1-\frac{x^2}{2!}+\frac{x^4}{4!}-\frac{x^6}{6!}+…\)
\(\sin x=x-\frac{x^3}{3!}+\frac{x^5}{5!}-\frac{x^7}{7!}\)
将\(x=i\theta\)带入得:
\(e^{i\theta}=1+\theta i-\frac{\theta^2}{2!}-\frac{\theta^3}{3!}i+\frac{\theta^4}{4!}+\frac{\theta^5}{5!}i-\frac{\theta^6}{6!}-\frac{\theta^7}{7!}i+…\)
\(e^{i\theta}=(1-\frac{\theta^2}{2!}+\frac{\theta^4}{4!}-\frac{\theta^6}{6!}+…)+i(\theta-\frac{\theta^3}{3!}+\frac{\theta^5}{5!}-\frac{\theta^7}{7!}+…)\)
即\(e^{i\theta}=\cos\theta+i\sin\theta\)
将欧拉公式带入到三角形式的表达式中就能得到复数的指数形式表达式:\(z=r(\cos\theta+i\sin\theta)=re^{i\theta}\)

单位复数根

在复数域内,有且仅有\(n\)个数,使得这个数的\(n\)次方等于1,我们把这样的数称为单位复数根,记作\(\omega_{n}^{i} (i\epsilon [0,n-1])\)
把\(\theta=2\pi\)带入欧拉公式,得\(e^{2\pi i}=1\)
所以\(\omega_{n}^{k}=(e^{\frac{2\pi i}{n}})^k\)
消去引理:\(\omega_{dn}^{dk}=\omega_{n}^{k}\)
证明:\(\omega_{dn}^{dk}=(e^{\frac{2\pi i}{dn}})^{dk}=(e^{\frac{2\pi i}{n}})^k=\omega_{n}^{k}\)

折半引理:\((\omega_{n}^{k})^2=\omega_{n/2}^{k}\)
证明:将\(d=\frac {1}{2}\)带入消去引理

求和引理:\(\sum_{i=0}^{n-1} (\omega_{n}^{k})^i=0\) (\(k\)不是\(n\)的倍数)
证明:利用等比数列求和公式,原式等于\(\frac{(\omega_{n}^{k})^n-1}{\omega_{n}^{k}-1}=\frac{0}{\omega_{n}^{k}-1}\)
因为分母不能为0,所以\(\omega_{n}^{k}\)不等于\(1\),所以\(k\)不是\(n\)的倍数.

循环性质:\((\omega_{n}^{k})^p=\omega_{n}^{pk}=\omega_{n}^{(pk\mod{n})}\)
证明:\(\omega_{n}^{kp}=\omega_{n}^{(kp\mod n+\left \lfloor \frac{kp}{n} \right \rfloor n)}=\omega_{n}^{(kp \mod n)}\)

对称性质:\(w_{n}^{k+\frac{n}{2}}=-w_{n}^{k}\)
证明:\(w_{n}^{k+\frac{n}{2}}=e^{\frac{2\pi ki}{n}+\pi i}=w_{n}^{k} e^{\pi i}=-w_{n}^{k}\)

离散傅里叶变换

多项式的两种表示方法

开头提到的多项式,都是用系数表达法来表示的。
也就是将次数界为\(n\)的多项式的系数\(a_0,a_1,…,a_{n-1}\)看成\(n\)维向量\(\vec{a}=(a_0,a_1,…,a_{n-1})\),\(\vec{a}\)称作多项式\(A(x)\)的系数表示。
事实上,除了系数表示\(A(x)=\sum_{i=0}^{n-1}a_i x^i\)还有一种表示方法:点值表示法。
一个次数界为\(n\)的多项式,就是\(n\)的点值对组成的集合。\((x_0,y_0),(x_1,y_1),…,(x_{n-1},y_{n-1})\) .对于\(0<=k<=n-1\),所有的\(x_k\)各不相同,记作\(y_k=A(x_k)\)
而离散傅里叶变换就是要快速求出多项式在这\(n\)的点的值

Cooley-Tukey算法

Cooley-Tukey算法是一种基于分治的算法
们取\(n\)个\(n\)次单位根 \(w_{n}^{0},w_{n}^{1},…,w_{n}^{n-1}\) 进行求值:\(A(w_{n}^{k})=\sum_{i=0}^{n-1}a_i w_{n}^{ki}\)
向量\(\vec{y}=(A(w_{n}^{0}),…,A(w_{n}^{n-1}))\)称作\(\vec{a}=(a_0,…,a_n-1)\)的离散傅里叶变换
接下来我们按照奇偶分开来算:
\(A(w_{n}^{k})=\sum_{i=0}^{n-1}a_i w_{n}^{ki}\)
\(=\sum_{i=0}^{\frac{n}{2}-1}a_{2i}w_{n}^{2ki}+w_{n}^{k}\sum_{i=0}^{\frac{n}{2}-1}a_{2i+1}w_{n}^{2ki}\)
\(=\sum_{i=0}^{\frac{n}{2}-1}a_{2i}w_{\frac{n}{2}}^{ki}+w_{n}^{k}\sum_{i=0}^{\frac{n}{2}-1}a_{2i+1}w_{\frac{n}{2}}^{ki}\) (折半引理)
而\(A(w_{n}^{k+\frac{n}{2}})=\sum_{i=0}^{\frac{n}{2}-1}a_{2i}w_{\frac{n}{2}}^{ki}-w_{n}^{k}\sum_{i=0}^{\frac{n}{2}-1}a_{2i+1}w_{\frac{n}{2}}^{ki}\)(对称性质)
这样问题就变成了求\(\frac{n}{2}\)个单位根的点值,问题的规模缩小了一半,所以是\(O(nlogn)\)的。

快速傅里叶变换的逆变换

求值与插值

对于一个多项式,如果知道它的系数表达式,我们很容易求出它的点值表达式,这一过程成为求值
如果知道它的点值表达式,让你求它的系数表达式,这一过程称为插值
定理:当插值多项式的次数界等于已知点值对的数目时,插值才是明确的
证明:\(y_k=A(x_k)\)等价于

其中,左边的矩阵称为范德蒙矩阵,其行列式\(Det=\prod_{0\leq j<k\leq n-1}(x_k-x_j)\)
如果所有\(x_k\)均不相等,那么其行列式不为\(0\),该矩阵可逆。
因此给定点值表达,能够唯一确定系数表达
所以如果我们知道了一个多项式的点值表示,就可以通过矩阵求逆的方法来算出系数向量
现在我们得到了点值表达式,那么如何求系数表达式呢?
矩阵求逆的复杂度是\(O(n^3)\)的,范德蒙矩阵求逆可以优化至\(O(n^2)\),但是复杂度依旧很高.
我们考虑构造一个现成的能算的东西进行优化

构造逆矩阵

我们现在已经得到了这样的方程:

记系数矩阵为\(V\),记下面的矩阵\(d_{ij}=w_{n}^{-ij}\)

它们相乘的结果\(E=DV\)满足\(e_{ij}=\sum_{k=0}^{n-1}w_{n}^{k(j-i)}\)
当\(i=j\)时,\(e_{ij}=n\)
当\(i\neq j\)时,\(e_{ij}=\sum_{k=0}^{n-1}(w_{n}^{(j-i)})^k=0\)(求和引理)
所以\(\frac{1}{n}D\)就是我们要求的逆矩阵,如下图:

这就相当于我们把单位复数根\(w^{k}_{n}\)换成\(w^{-k}_{n}\)再做一遍离散傅里叶变换结果除以\(n\)就行了

模板代码

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
const int maxn = 1200000;
const double pi = acos(-1.0);
struct Complex {double r,i;Complex(double r,double i):r(r),i(i){}Complex(){};
};
Complex operator + (Complex a,Complex b) {return Complex(a.r+b.r,a.i+b.i);
}
Complex operator - (Complex a,Complex b) {return Complex(a.r-b.r,a.i-b.i);
}
Complex operator * (Complex a,Complex b) {return Complex(a.r*b.r-a.i*b.i,a.r*b.i+b.r*a.i);
}
int n,m,L[maxn],R[maxn];
Complex A[maxn<<1],B[maxn<<1];
inline void read(int &x) {char ch=getchar();x=0;while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
}
inline void read(double &x) {char ch=getchar();x=0;while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9') {x=10*x+ch-'0';ch=getchar();}
}
void fft(Complex *a,int n,int inv) {for(register int i=1,j=n/2;i<n-1;++i) {if(i<j) std::swap(a[i],a[j]);int k = n>>1;while(j>=k) {j-=k;k>>=1;}j+=k;}for(register int j=2;j<=n;j<<=1) {Complex wn(cos(2*pi/j*inv),sin(2*pi/j*inv));for(register int i=0;i<n;i+=j) {Complex w(1,0);for(register int k=i;k<i+(j>>1);k++) {Complex u=a[k],t=a[k+(j>>1)]*w;a[k]=u+t;a[k+(j>>1)]=u-t;w=w*wn;}}}if(inv==-1) for(register int i=0;i<n;i++) a[i].r=a[i].r/n+0.5;
}
int ans[maxn<<1];
int main() {read(n);read(m);for(register int i=0;i<=n;i++) read(A[i].r);for(register int i=0;i<=m;i++) read(B[i].r);int limit = 1;while(limit<=n+m) limit<<=1;fft(A,limit,1);fft(B,limit,1);for(register int i=0;i<=limit;i++) {A[i]=A[i]*B[i];}fft(A,limit,-1);for(register int i=0;i<=m+n;i++) printf("%llu ",(unsigned long long int)(A[i].r));return 0;
}

转载于:https://www.cnblogs.com/Syameimaru/p/9950322.html

【文文殿下】快速傅里叶变换(FFT)学习笔记相关推荐

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

    文章目录 FFT ( 快速傅里叶变换 ) 学习笔记 参考文章: 多项式 系数表示法 点值表示法 复数 前置芝士 向量 弧度制 定义 运算法则 单位根 快速傅里叶变换: 快速傅里叶逆变换 (IFFT): ...

  2. FFT(快速傅里叶变换)学习笔记

    简介 FFTFFTFFT (法法塔)是个什么玩意?他的全名叫快速傅里叶变换(然而貌似和傅里叶并没有太大关系),用来快速求出多项式的点值表示,这个东西一般用来解决多项式相乘的问题. 一般的高精度乘法,我 ...

  3. 快速傅里叶变换FFT学习小记

    FFT学得还是有点模糊,原理那些基本还是算有所理解了吧,不过自己推这个推不动. 看的资料主要有这两个: http://blog.miskcoo.com/2015/04/polynomial-multi ...

  4. 【文文殿下】Manache算法-学习笔记

    Manache算法 定义:是一个判断回文子串的算法,我们结合例题解释: 题目:给定一个长度为 n 的字符串 S,求其最长回文子串 一个字符串是回文的,当且仅当反转后的串与原串完全相等 分析:对于这个题 ...

  5. 【近万字】分数傅里叶变换课程学习笔记

    学习自"课堂在线"平台,北京理工大学陶然教授的课程视频,讲解的非常详细全面,数学公式推导都有,以下为学习笔记,仅记录要点部分. 注:学习此课程,按重要程度排序,需要有信号与系统.数 ...

  6. OpenCV快速傅里叶变换(FFT)用于图像和视讯流的模糊检测

    OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测 翻译自[OpenCV Fast Fourier Transform (FFT) for blur detection in images ...

  7. 图像傅里叶变换(快速傅里叶变换FFT)

    学习DIP第7天,图像傅里叶变换 转载请标明出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对 ...

  8. 基于python的快速傅里叶变换FFT(二)

    基于python的快速傅里叶变换FFT(二) 本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点   FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算 ...

  9. 基于python的快速傅里叶变换FFT(一)

    基于python的快速傅里叶变换FFT(一) FFT可以将一个信号变换到频域.有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了.这就是很多信号分析采用FFT变换的原因. ...

最新文章

  1. 计算机将成为学生们的老师英语,七年级英语(牛津版)第一学期7A完成句子练习题...
  2. gorm crud简单代码示例
  3. SAP UI5 应用开发教程之六十二 - 基于 OData V4 的 SAP UI5 表格控件使用方法介绍
  4. 第5章 Python 数字图像处理(DIP) - 图像复原与重建5 - 均匀噪声
  5. mysql 升序_MySQL“自古以来”都有一个神秘的HANDLER命令
  6. 55寸鸿蒙安卓,深网|荣耀智慧屏发布:搭载鸿蒙系统 配55英寸屏3799元起
  7. Linux 五种I/O模型
  8. 14-循环队列实现(C语言)
  9. Easyrecovery13 for mac 官方版下载
  10. Mysql 省市区字典(带层级,带经纬度,带拼音)
  11. element-ui MessageBox 弹框判断确认和取消
  12. 软件测试之如何测试数据?
  13. 超详细的《使用腾讯云移动直播开发连麦》
  14. java我们一起打雪仗_一起打雪仗的作文
  15. J2me项目实例------网络通讯录(1) (转)
  16. [托业]TOEIC词汇汇总(完整篇)4
  17. 曼尼托巴大学计算机科学硕士,曼尼托巴大学电气和计算机工程硕士解析
  18. JAVA 数据类型强制转换详解
  19. sql语句中使用临时表
  20. 【文献笔记】【部分精读】【CIR】Angle of Arrival Estimation based on Channel Impulse Response Measurements

热门文章

  1. 更换YUM及升级包方法
  2. 节能与新能源汽车技术路线图2.0_节能与新能源汽车技术路线图(2.0版)
  3. php编程输出心形图案_利用php输出不同的心形图案,php心形图案_PHP教程
  4. 计算机更改本地用户,win10电脑更改本机账户名的详细步骤(图文)
  5. win8如何卸载mysql5.0_Win8如何卸载Windows的服务?卸载Windows的服务的方法和步骤
  6. 恢复应用_ofo年底裁员超50%,苹果应用市场恢复畅销榜,支付宝15周年微电影发布,MIUI来电留言功能即将下线,这就是今天的其他大新闻!...
  7. 自动化监控--zabbix安装和配置详解
  8. Linux下scp无密码上传 下载 文件 目录的方法
  9. VS2015 无法启动 IIS服务器
  10. android 第三方登录 --- QQ