FFT, NTT, FWT 学习笔记
为什么学 FFT
退役(很早)之前听说 FFT 很神(e)奇(xin),Po 姐来讲的时候也是膜(sha)了(ye)一(bu)发(dong),于是就放那里了。退役之后有(xian)了(de)时(mei)间(shi),并且在篮球赛之前立了赢一场的 flag 否则学 FFT 结果又双叒叕全输了,于是下面就是成果了……网上 FFT 讲解多得是不看也罢……
如果想要深入了解,请参考王逸松在 2018 年全国青少年信息学奥林匹克竞赛冬令营的讲课傅里叶变换及其在 OI 中的应用。
什么是 FFT?为什么 FFT?
什么是 FFT?
FFT (Fast Fourier Transform),全名快速傅里叶变换,这与 Fourier 变换只有半毛钱的关系,Fourier 变换是分析波的成分的方法,通过推广 Fourier 变换得到了 FFT ,为了展示区别和联系,下面是 Fourier 变换和 Fourier 逆变换的公式。
Fourier 变换:
Fourier 逆变换:
其中
为什么 FFT?
从一个简单问题说起:大整数乘法。在做 Vijos P2000 的时候,看数据范围
并不是。从算法优化上可以实现为
(初中知识)多项式
定义
我们把形如
以上内容均为初二(我记得是)的内容,不明白的自觉面壁思过(初中数学老师:这个定义抄
下面就是没学过的了。
为方便表示,我们记多项式
我们规定:严格大于
下面无特殊说明,多项式均用
多项式的两种表示法
系数(插值)表示法
我们知道,向量是个好东西(蛤?),矩阵也是个好东西(蛤?),于是我们把三者结合起来看(蛤玩意?)。
我们将
在选修 4-2 中,我们知道向量与矩阵有着密切联系,这就是为什么我们把多项式,向量和矩阵联系起来。(然而我们并没选 4-2 蛤蛤蛤)
于是这个
点值表示法
我们把多项式
我们知道一个
到这里,是不是差不多忘了要干什么了……
多项式的运算
多项式求值
对于一个多项式
学过必修三吗?
学过必修三还不会?
拿出数学必修三翻到
秦九韶算法可以大量减少乘法和加法次数,并且把运算量简化为
多项式加法
没啥难度,直接加即可:
这个操作可以
多项式乘法
这就是个开括号的问题……
两个次数界为
我们把不足的次数用系数
考虑怎样的两项乘完后,结果的幂指数为同一个。即
那么乘完之后,
我们把中间的那个加法,即
这样,朴素算法时间复杂度为
但是点值表达式的表示就很好了,直接乘起来就好了嘛!
设两个多项式的次数界均为
设
插值 - 点值转换
就要接近重点了同志们加油!
先定义两个运算:
- 定义一种运算,可以将系数表示转化为点值表示,记为
; - 定义其逆运算,即从一个多项式的点值表示确定其系数表示为插值。记为
。
第一个运算在
答案是肯定的。我们把这些点代入,可以得出一个
当然可以拿矩阵证明网上多得是。
那么就很尴尬,
所以我们还需要一些姿势。
(高中知识)复数
一些奇奇怪怪的问题无法解决,可以把它从实数域扩展到复数域上解决,加入了复数这种类似向量的东西,问题就会变得简单。
噫,向量?点值表示不就是个向量吗!
定义
可以参考 复数 - OI Wiki。
一堆定义就不说了,选修 2-2 内容,这里简单的强调一些运算:
设
设
设
这是学过的,下面就说说没学过的。
单位根
根?方程的根?什么方程的根?
定义:
当我们把问题引入复数域,
欧拉公式
一个很强的公式。内容是:
式子很简单,证明如下:
由 Taylor 公式:
将 Taylor 公式推广到复数域上,有复数运算
证毕。
将
将
我们不是要解
那么
下面就是一些数论问题了……
记
这不一样吗……
所以可以证明
于是记这些根为
问题得证。
三个引理
消去引理
内容:当
证明:
很简单……也很智障
折半引理
内容:如果
证明:
还行吧……可以看出,
更一般的结论:
求和引理
内容:对于
证明:
注意:很多步骤。
现在全都就绪了,终于要到目标了……
离散傅里叶变换(DFT)
DFT,即 Discrete Fourier Transform,离散 Fourier 变换,就是我们之前定义的那个,现在有了复数,我们就可以在
我们想在尽可能快的时间里获得
我们将多项式按照指数的奇偶分类,记原多项式为
通过观察可知,
那么,对于
这样,由奇偶性使得需要代入的值范围减半,递归做下去就行了。
时间复杂度为:
因此,对于单位根的多项式求值,其实是均摊
因为永远是奇偶合并,如果想要更方便地合并必然
逆离散傅里叶变换(IDFT)
IDFT,即 Inverse Discrete Fourier Transform,逆离散傅里叶变换,还是我们之前定义的那个。我们在
我们说过,IDFT 相当于解个
这同时也是做 DFT 时我们利用的矩阵。只不过做 DFT 时右边是未知的,这次
记上面的系数矩阵为
记此矩阵为
当
当
记单位矩阵为
这和 DFT 的操作很像,所以用 DFT 的过程实现 IDFT 即可。
负号?把
现在 IDFT 也是
至此,所有的时间都是
NTT
我们学过了 FFT,发现很滋磁。但是 FFT 涉及浮点数,有可能有精度问题,所以这就很闹心了……发现精度问题出现在 DFT 和 IDFT 中求
那么整数范围内的问题需要数论解决,这就导致了 NTT(也叫 FNT)的诞生。
可以说,精度问题主要由
好像也就是三个引理吧…… 列出来所用的性质们:(一些条件有省略,具体请详见 FFT 学习笔记)
; 且 , ;- (折半引理)
, ; - (求和引理)
。
所以,我们需要在整数范围内找到一个符合这四条性质的一种数。于是我们找到了一种特殊的数——原根。
定义如果所有与
为了方便计算,我们取模数为一个质数
然后,我们用
然后我们验证一下性质是否符合。
对于第一条,由 Fermat's little theorem,
对于第二条,根据第一条可以看出,原根同单位根一样,构成了一个乘法群。具体可以用第一条证明。因此第二条也是满足的。
对于第三条,化简一下指数,拆成两项相乘的形式,然后接着用第一条,还是可以得证。
对于第四条,运用等比数列求和,然后也可以得证。
如果模数任意呢?
如果要模数是
然后按每个
又双叒叕 CRT 合并……
本身 NTT 常数就比较大,和 FFT 差不多吧……(中间有快速幂)。
Po 姐:「此外,一个答案模一个数的计数问题必须用 NTT。」
这里是一些常用质数的原根。
FWT
FWT 是一种类似于 FFT 的变换。我们都知道对于数组
那么 FWT 只是把计算下标的加减运算改为了逻辑运算(与、或、异或等)。
比如与运算下的 FWT 表示为:
那么怎么做……
以下三位大爷写得已经足够好就不造轮子了……
Fast Walsh-Hadamard Transform - Picks's Blog
FWT 详解 知识点 - neither_nor
HDU 5909 Tree Cutting 树形 DP+快速沃尔什变换 - PoPoQQQ
膜拜以上三位大爷%%%
实现问题
说是一回事,写是另一回事。
奇偶分组这个玩意就很坑,容易发现,设
不过 FFT 本身常数巨大,主要因为 double
类型的计算时间,还有使用
我们看到,DFT 做完后,得到的是将
FFT 和 FWT 都在图像处理,音频处理方面有较大应用。
终于把我的 flag 填完了我好开心啊!!!