多项式各种算法学习笔记

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

1.前置技能

复数:
基本表示法及性质:

i = − 1 i=\sqrt{-1} i=1

i i i是虚数单位

1.坐标(代数)形式:
z = a + b i z=a+bi z=a+bi

当b为0是z为实数,当a为0时为纯虚数

注:复数包括实数和虚数,虚数下有纯虚数

虚数z对应了复平面上的一点(a,b)

运算法则:
设复数 z 1 , z 2 , z 1 = a + b i , z 2 = c + d i z_1,z_2,z_1=a+bi,z_2=c+di z1,z2,z1=a+bi,z2=c+di

加法: z 1 + z 2 = ( a + c ) + ( b + d ) i z_1+z_2=(a+c)+(b+d)i z1+z2=(a+c)+(b+d)i
减法: z 1 − z 2 = ( a − c ) + ( b − d ) i z_1-z_2=(a-c)+(b-d)i z1z2=(ac)+(bd)i
乘法: z 1 ∗ z 2 = ( a c − b d ) + ( b c + a d ) i z_1*z_2=(ac-bd)+(bc+ad)i z1z2=(acbd)+(bc+ad)i
除法: z 1 z 2 = ( a c + b d ) + ( b c − a d ) i ( c 2 + d 2 ) \dfrac{z_1}{z_2}=\dfrac{(ac+bd)+(bc-ad)i}{(c^2+d^2)} z2z1=(c2+d2)(ac+bd)+(bcad)i

2.三角形式

z = r ( c o s θ + i s i n θ ) z=r(cos \theta+isin\theta) z=r(cosθ+isinθ)

θ \theta θ是复数 z z z的幅角, r r r是该复数的模长

这种形式下的乘法和除法运算更方便,通过和角公式,对于复数 z 1 = r 1 ( c o s θ 1 + i s i n θ 1 ) , z 2 = r 2 ( c o s θ 2 + i s i n θ 2 ) z_1=r_1(cos\theta_1+isin\theta_1),z_2=r_2(cos\theta_2+isin\theta_2) z1=r1(cosθ1+isinθ1),z2=r2(cosθ2+isinθ2)
那么:
z 1 z 2 = r 1 r 2 ( c o s ( θ 1 + θ 2 ) + i s i n ( θ 1 + θ 2 ) ) z 1 z 2 = r 1 r 2 ( c o s ( θ 1 − θ 2 ) + i s i n ( θ 1 − θ 2 ) ) z_1z_2=r_1r_2(cos(\theta_1+\theta_2)+isin(\theta_1+\theta_2))\\ \dfrac{z_1}{z_2}=\dfrac{r_1}{r_2}(cos(\theta_1-\theta_2)+isin(\theta_1-\theta_2))\\ z1z2=r1r2(cos(θ1+θ2)+isin(θ1+θ2))z2z1=r2r1(cos(θ1θ2)+isin(θ1θ2))

几何意义:相当于把该复数 拉长/缩短 到另一个复数模长 倍/分之一 ,然后 顺时针/逆时针 旋转另一个复数的幅角大小的角度

于是有了如下非常有用的公式:
z n = ( r ( c o s θ + i s i n θ ) ) n = r n ( c o s   n θ + i s i n   n θ ) z^n=(r(cos\theta+isin\theta))^n=r^n(cos\ n\theta+isin\ n\theta) zn=(r(cosθ+isinθ))n=rn(cos nθ+isin nθ)

3.指数形式

z = r e i θ z=re^{i\theta} z=reiθ

于是我们知道了: e i θ = c o s θ + i s i n θ e^{i\theta}=cos\theta+isin\theta eiθ=cosθ+isinθ

可以发现: e i π = − 1 e^{i\pi}=-1 eiπ=1
(优美)

这个算乘除法就更好算了:
有:
z 1 z 2 = r 1 r 2 e i ( θ 1 + θ 2 ) z 1 z 2 = r 1 r 2 e i ( θ ) z_1z_2=r_1r_2e^{i(\theta_1+\theta_2)}\\ \dfrac{z_1}{z_2}=\dfrac{r_1}{r_2}e^{i(\theta)}\\ z1z2=r1r2ei(θ1+θ2)z2z1=r2r1ei(θ)

上面的那个公式就可写成这样:
z n = r n e i ( n θ ) z^n=r^ne^{i(n\theta)} zn=rnei(nθ)

4.单位复数根

学FFT最重要的就这个了吧
设有如下方程:
z n = 1 z^n=1 zn=1

这方程的复数根 z z z n n n次单位根,通常记为 w w w
这样的根 w w w有n个,也就是说 n n n次单位根有 n n n个,记为 w k ( k = 0 , 1 , 2 , … n − 1 ) w_k (k=0,1,2,\dots n-1) wk(k=0,1,2,n1)
其中:
w k = c o s 2 k π n + i s i n 2 k π n = e 2 π k i n w_k=cos\frac{2k\pi}{n}+isin\frac{2k\pi}{n}=e^{\frac{2\pi ki}{n}} wk=cosn2kπ+isinn2kπ=en2πki

不难发现其实 n n n次单位复数根就是把复平面上的单位圆 n n n 等分后的那些 n n n等分点

一些次数单位的单位根举例:

1次单位根: 1 1 1
2次单位根: 1 , − 1 1,-1 1,1
3次单位根: 1 , − 1 + 3 i 2 , − 1 − 3 i 2 1,\frac{-1+\sqrt{3}i}{2},\frac{-1-\sqrt{3}i}{2} 1,21+3 i,213 i
… \dots
其实就是个解二元n次方程

可以发现1是任意次的单位复数根,-1是任意偶数次单位复数根

某些引理:

1.消去引理
w d n d k = w n k w_{dn}^{dk}=w_n^k wdndk=wnk

把复数的指数形式带进去就可以了
说人话就是不同次数的单位根可以互相转化

2.折半引理
假设 n n n是大于0的偶数:
( w n k + n 2 ) 2 = w n 2 k + n = w n 2 k ∗ w n n = ( w n k ) 2 (w_n^{k+\frac{n}{2}})^2=w_n^{2k+n}=w_n^{2k}*w_n^n=(w_n^{k})^2 (wnk+2n)2=wn2k+n=wn2kwnn=(wnk)2

说人话就是n次单位复数根的前后两半平方后是对应相等的

3.求和引理

对于大于1的整数n和小于等于n的整数k有:
∑ i = 0 n − 1 ( w n k ) i = 0 \sum_{i=0}^{n-1}(w_n^k)^i=0 i=0n1(wnk)i=0

这就是个等比数列求和

2.步入正题

常规的一个最高次数为n-1的多项式的表示形式是系数表示法,如:
A ( x ) = a 0 + a 1 x + a 2 x 2 + a 3 x 3 + ⋯ + a n − 1 x n − 1 A(x)=a_0+a_1x+a_2x^2+a_3x^3+\dots+a_{n-1}x^{n-1} A(x)=a0+a1x+a2x2+a3x3++an1xn1
一共有n项
按照朴素的多项式乘法(卷积),就是每一项两两相乘,复杂度为 O ( n 2 ) O(n^2) O(n2)

如果我们把多项式看成一个函数,我们取图像上的n个点来表示这个函数也即该多项式,这样的表示法叫做点值表示法

对于两个n-1次多项式,由于我们最后卷积出来的多项式是2n-2次的,如果我们知道了卷积后的多项式函数图像上的至少2n-1个点,那么我们就可以确定这个多项式了

所以有如下想法:
现在原来的两个多项式上选取好x值相同的点(个数为原来两多项式次数的和加1),用 O ( n ) O(n) O(n)的时间将选的点的y值相乘,得到的值用某种方法~~(待定系数法)~~转化为多项式系数的形式

如果选取的x都是n次单位复数根的k次方,那么以上两个过程就是 D F T DFT DFT I D F T IDFT IDFT

1. D F T DFT DFT

离散傅里叶变换:
对于 k ∈ [ 0 , n − 1 ] , k\in [0,n-1], k[0,n1],和n-1次多项式 A ( x ) , A(x), A(x),定义:
y k = A ( w n k ) = ∑ i = 0 n − 1 a i ( w n k ) i y_k=A(w_n^k)=\sum_{i=0}^{n-1}a_i(w_n^k)^i yk=A(wnk)=i=0n1ai(wnk)i

这个叫做离散傅里叶变换,记做 y = D F T n ( a ) y=DFT_n(a) y=DFTn(a)

朴素求 D F T DFT DFT,是 O ( n 2 ) O(n^2) O(n2)

2. I D F T IDFT IDFT

逆离散傅里叶变换:

就是 D F T DFT DFT的逆运算,用于求出多项式的系数a,记为 D F T − 1 DFT^{-1} DFT1

本人太弱不会证,丢个式子:
a k = 1 n ∑ i = 0 n − 1 y i ( w n − k ) i a_k=\dfrac{1}{n}\sum_{i=0}^{n-1}y_i(w_n^{-k})^i ak=n1i=0n1yi(wnk)i

由于写的时候系数表达式和点值表达式是共用的数组,所以写起来和 D F T DFT DFT没什么差别

3. F F T FFT FFT

快速傅里叶变换:

是一种快速求出 D F T DFT DFT D F T − 1 DFT^{-1} DFT1的算法,利用了单位复数根的优良性质

我们先列出朴素求 D F T DFT DFT的步骤,为了方便这里先不妨假设多项式次数为2的幂:
1.求出n次单位复数根的幂: w n 0 , w n 1 , w n 2 . . . . . w n n − 1 w_n^0,w_n^1,w_n^2.....w_n^{n-1} wn0,wn1,wn2.....wnn1
2.代入多项式 A ( x ) A(x) A(x),求得以下式子:
A ( w n 0 ) = a 0 + a 1 w n 0 + a 2 ( w n 0 ) 2 + a 3 ( w n 0 ) 3 + … a n − 1 ( w n 0 ) n − 1 A ( w n 1 ) = a 0 + a 1 w n 1 + a 2 ( w n 1 ) 2 + a 3 ( w n 1 ) 3 + … a n − 1 ( w n 1 ) n − 1 A ( w n 2 ) = a 0 + a 1 w n 2 + a 2 ( w n 2 ) 2 + a 3 ( w n 2 ) 3 + … a n − 1 ( w n 2 ) n − 1 A ( w n 3 ) = a 0 + a 1 w n 3 + a 2 ( w n 3 ) 2 + a 3 ( w n 3 ) 3 + … a n − 1 ( w n 3 ) n − 1 … … … … … … … … … … … … … … … … … A ( w n n − 1 ) = a 0 + a 1 w n n − 1 + a 2 ( w n n − 1 ) 2 + a 3 ( w n n − 1 ) 3 + … a n − 1 ( w n n − 1 ) n − 1 A(w_n^0)=a_0+a_1w_n^0+a_2(w_n^0)^2+a_3(w_n^0)^3+\dots a_{n-1}(w_n^0)^{n-1}\\ A(w_n^1)=a_0+a_1w_n^1+a_2(w_n^1)^2+a_3(w_n^1)^3+\dots a_{n-1}(w_n^1)^{n-1}\\ A(w_n^2)=a_0+a_1w_n^2+a_2(w_n^2)^2+a_3(w_n^2)^3+\dots a_{n-1}(w_n^2)^{n-1}\\ A(w_n^3)=a_0+a_1w_n^3+a_2(w_n^3)^2+a_3(w_n^3)^3+\dots a_{n-1}(w_n^3)^{n-1}\\ \dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\\ A(w_n^{n-1})=a_0+a_1w_n^{n-1}+a_2(w_n^{n-1})^2+a_3(w_n^{n-1})^3+\dots a_{n-1}(w_n^{n-1})^{n-1}\\ A(wn0)=a0+a1wn0+a2(wn0)2+a3(wn0)3+an1(wn0)n1A(wn1)=a0+a1wn1+a2(wn1)2+a3(wn1)3+an1(wn1)n1A(wn2)=a0+a1wn2+a2(wn2)2+a3(wn2)3+an1(wn2)n1A(wn3)=a0+a1wn3+a2(wn3)2+a3(wn3)3+an1(wn3)n1A(wnn1)=a0+a1wnn1+a2(wnn1)2

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值