zoukankan      html  css  js  c++  java
  • 多项式初步

    最近在看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))的。

    拉格朗日插值

    [A(x)=sumlimits_{k=0}^{n-1}y_kfrac{prodlimits_{i e k}(x-x_i)}{prodlimits_{i e k}(x_k-x_i)} ]

    套式子就好了。
    简单证明:
    如果这个多项式能和原点值表达取到相同的值,那么这个插值就是对的。

    因为选取的(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)

    可以画在一个坐标系里,就像是向量一样。

    但是和向量运算稍有不同

    复数加法

    直接加,合并同类项。

    复数减法

    同上

    复数乘法

    直接乘,然后合并。

    [(a+bi)(c+di)=ac+adi+cbi+bdi^2 ]

    [=(ac-bd)+(ad+cb)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)的单位复数根分成奇数次和偶数次进行讨论,发现他们在平方后都会变成偶数次,也就变成了原来的一半。
    在图上看会很显然。

    求和引理

  • 相关阅读:
    vm8.0安装mac提示中断导致虚拟cpu进入终止状态……vm重启的解决办法
    WPF和WindowsForm下的按下Enter跳转下一个控件通用方法
    【Z】oledb读写excel出现“操作必须使用一个可更新的查询”错误
    关于系统编码的那点事
    【Z】使用OleDbCommandBuilder时出现“Insert into 语句的语法错误”
    Thread 初学(二)——线程同步
    Oracle中针对一张表建立触发器,并且触发器也处理同一张表的数据(ora04091 错误)
    Thread初学 (一)
    【Z】使用SQL Server的OPENROWSET函数
    13个绚丽的Jquery 界面设计
  • 原文地址:https://www.cnblogs.com/oiertkj/p/11614147.html
Copyright © 2011-2022 走看看