最近在看HZ的多项式视屏,感觉正如GSH所说的,多项式还挺好玩的。
多项式
多项式差不多就是初中时候学的多项式。
一个以(x)为变量的多项式定义在一个代数域(F)上,将函数(A(x))表示为形式和:
(A(x)=sumlimits_{i=0}^{n-1}a_ix^i)
初中时常见的(5x^2+8x+1,10x^3+8x^2-2)就是多项式。
(a_0,a_1,...,a_{n-1})称为多项式的系数。
其中的数域F可以为复数域,实数域...
次数和次数界
和初中的次数定义相同,记多项式中次数最大的为整个多项式的次数。
如果多项式(A)的最高次的非零系数是(a_k),那么这个多项式的次数就是(k)
记作(degree(A)=k)
举个例子:
(A(x)=10x^3+8x^2-2)
(degree(A)=3)
次数界就是次数的上界,相当于是给定的次数范围。
任何一个大于多项式次数的整数都可以作为这个多项式的次数界。
即你不需要次数真的卡在上界上,次数可以小于次数界。
如上的多项式次数界可以是任何一个大于等于(4)的整数。
多项式加法
和初中的多项式加法一样,直接合并同类项就可以。
两个次数界为(n)的多项式相加的多项式次数界也为(n)
(A(x)=sumlimits_{i=0}^{n-1}a_ix^i)
(B(x)=sumlimits_{i=0}^{n-1}b_ix^i)
(C(x)=A(x)+B(x))
(C(x)=sumlimits_{i=0}^{n-1}(a_i+b_i)x^i)
注:次数界不同肯定是能加能乘的,相当于高次的系数是0。
多项式乘法
和初中的多项式乘法一样,直接一个一个分别乘进去再合并同类项就可以。
两个次数界为(n)的多项式乘出来是一个次数界为(2n-1)的多项式,因为假设两个多项式的次数都是(n-1),能乘出来的最大次数为(2n-2),次数界为(2n-1)。
可以看出来多项式乘法是一个卷积。
(A(x)=sumlimits_{i=0}^{n-1}a_ix^i)
(B(x)=sumlimits_{i=0}^{n-1}b_ix^i)
(C(x)=A(x)B(x))
(C(x)=sumlimits_{i=0}^{2n-2}x_isumlimits_{k=0}^ia_kb_{i-k})
此时
(degree(C)=degree(A)+degree(B))
多项式的系数表达
把多项式的系数写成一个(n)维系数向量。
((a_0,a_1,a_2,...,a_{n-1}))
此时多项式乘法就是一个卷积了。
卷积满足交换律,结合律,分配律。
这个显然,要不然从初中建立的数学体系就崩塌了。
多项式的点值表达
随便取(n)((n)为次数界)个不同的(x),记为(x_i),(y_i=A(x_i))
于是形成了(n)个点。
两个多项式如果为取同样(x_i)的点值表达,那么这两个多项式的乘法是(O(n))的。
显然只需要将(y_i)乘起来就可以了。
当然为了确定乘出来的多项式要乘(2n-1)项。
插值多项式唯一性定理
(n)个点的点值表达唯一确定一个次数界为(n)的多项式。
显然?
把这么多点带进去可以得到一个n元n次方程组。
它是可以解出来的。
求值
就是把一些数带到多项式里面求一下值。
也就是说把系数表达转化为点值表达。
暴力是(O(n^2))的
插值
把点值表达再变回系数表达。
暴力也是(O(n^2))的。
拉格朗日插值
套式子就好了。
简单证明:
如果这个多项式能和原点值表达取到相同的值,那么这个插值就是对的。
因为选取的(x)互不相同,所以底下是不会出现(0)的。
设当前选到的值为(x_j),当枚举到的(y)是(y_j)时,后面的式子上下一样,为1。
当枚举到的(y)不为(y_j)时,分子上的式子会出现(x_j-x_j)也就为0了。
最后算出来的值一定是(y_j)
所以这样就插出来了。
FFT
FastFastTle
FFT是用来快速做多项式乘法的。
通过上述的东西可以知道点值表达式进行乘法的复杂度非常优秀。
如果能快速的把系数表达式转化为点值表达式,进行(O(n))的乘法,再快速地将点值表达式转化为系数表达式,那就很好了。
这可能需要我们进行巧妙的选点。
FFT能在(O(nlog n))的时间复杂度内完成上述第一步和第三步。
它通过选择使用单位复数根来进行优化。
复数
并不知道为什么会有人想出来这种奇怪的东西。
高考也要学。
复数可以表示为(a+bi)
其中(i)是虚数单位。
(i^2=-1,sqrt{-1}=i)
可以画在一个坐标系里,就像是向量一样。
但是和向量运算稍有不同
复数加法
直接加,合并同类项。
复数减法
同上
复数乘法
直接乘,然后合并。
复数和实数的乘除
直接乘就完了。
复数的三角函数表示
因为复数是可以画在坐标轴里的。
所以可以用三角函数表示。
设一个复数的模长为(R),且这个复数与(x)轴的夹角为(alpha)那么这个复数可以表示为(R(cosalpha+sinalpha i))
复数乘法在坐标系中的表示
以一个模长为1的复数的平方为例。
((cosalpha+sinalpha i)^2=cos^2alpha+2sinalphacosalpha i-sin^2alpha)
然后用一些三角函数的公式。
(cos^2alpha+2sinalphacosalpha i-sin^2alpha=cos2alpha+sin2alpha)
发现它刚好是一个二倍角。
再举一个一般情况,这种情况正确就可以推到所有情况。
((cosalpha+sinalpha i)(cos heta+sin heta i))
(=cosalphacos heta+sinalphacos heta i+cosalphasin heta i-sinalphasin heta)
(=cos(alpha+ heta)+sin(alpha+ heta)i)
所以我们可以得到一个结论,复数乘法相当于是在坐标轴中旋转。
欧拉公式
很著名的公式,但是我不会证。
(e^{ix}=cos x+isin x)
(e^{ipi}+1=0)
单位复数根
(n)次单位复数根指的是满足(omega^n=1)的复数(omega)
(n)次单位复数根恰好有n个,分别记为(omega_n^0,omega_n^1,omega_n^2,omega_n^3,omega_n^4,...,omega_n^{n-1})
其中主(n)次单位复数根为(e^{frac{2pi i}{n}}=cos(frac{2pi}{n})+isin(frac{2pi}{n}))
更直观的将就是将单位圆分成(n)份后,从(x)轴正半轴开始的第一条线段表示的复数。
其他所有的(n)次单位复数根都是它的幂次。
所以可以发现这(n)个复数将单位圆(n)等分。
FFT的推倒
消去引理
对于任何整数(n≥0,k≥0,d>0),有(ω_{dn}^{dk}=ω_n^k)
从几何意义的角度很好证明,同时把单位圆少分几块就可以了。
如果用公式证明的话直接套欧拉公式就可以了,然后会发现上下消掉了。
消去引理推论
对于任何偶数(n>0)
有(omega_n^{frac{n}{2}}=omega_2=-1)
显然
转圈转到一半就是(-1)
折半引理
如果(n>0)为偶数,那么(n)个(n)次单位复数根的平方集合就是(n/2)个(n/2)个单位复数根的集合。
因为懒得打式子,就感性证明了。
把(n)的单位复数根分成奇数次和偶数次进行讨论,发现他们在平方后都会变成偶数次,也就变成了原来的一半。
在图上看会很显然。