好记性不如烂键盘|ू・ω・` )
众所周知红小豆没有一点点数学基础,只好从爬出土开始
只是个人的学习笔记,如果有什么地方不清楚可见下列神仙的blog
参考神仙blog:大佬整理的大佬的多项式相关的思路https://www.cnblogs.com/yoyoball/p/8724115.html
大佬的多项式乘法与FFThttp://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transform
大佬的多项式除法http://blog.miskcoo.com/2015/05/polynomial-division
大佬的多项式求逆http://blog.miskcoo.com/2015/05/polynomial-inverse
大佬的BM原理https://zerol.me/2018/02/06/linearly-recurrent-sequence/
大佬的BM及板子https://www.cnblogs.com/zhouzhendong/p/Berlekamp-Massey.html
杜教的板子和一道题https://www.cnblogs.com/zhgyki/p/9671855.html
从多项式开始
多项式的系数表示法:系数可看作n+1维向量 点值表示法:(xi,A(xi))
n次单位根即满足zn=1的复数,分布在复平面的单位圆上构成一个正n边形。由复数乘法 模长相乘,幅角相加(突然想到电路分析。。)知n次单位根的模长为1,幅角的n倍为0——e2πki/n,k=0,1,2,⋯,n−1,可通过欧拉公式进行算术表示。
用w表示e2πk/n,n个n次根wn0、wn1、wn2……
多项式的乘法,就像手算一样一项一项去乘的话是O(n2)的,而用点值表示的话,只需要将n+1个点依次相乘就可以得到新的多项式的点值表示,现在的问题就是点值表示与系数表示的转换方法。
快速傅里叶变换(FFT)
可分为O(nlogn)的DFT(离散F变换)部分(数到点)和同样复杂度的IDFT(F逆变换)部分(点到数)
Cooley-Turkey算法 设n-1次多项式A(x),n=pow(2,m)若不足可视高次项系数为0,将A(x)的每一项按指数奇偶分类,则
A(wnk)=Σai*wnki(i∈[0,n-1])
=Σa2i*wn2ki(i∈[0,n/2-1])+Σa2i+1*wnk(2i+1)(i∈[0,n/2-1])
=Σa2i*wn2ki(i∈[0,n/2-1])+ wnk *Σa2i+1*wn2ki(i∈[0,n/2-1])
看起来还是有n个要代入,而由单位根指数部的变换可知wn2=wn/2(写成e的形式就很清楚了),所以实际上少了一半(证明可从单位圆等分对称的正负值的平方相等入手).
于是对于k<n/2,A(wnk)=Σa2i*wn/2ki(i∈[0,n/2-1])+ wnk *Σa2i+1*wn/2ki(i∈[0,n/2-1])
A(wnk+n/2)=Σa2i*wn/2ki(i∈[0,n/2-1])- wnk *Σa2i+1*wn/2ki(i∈[0,n/2-1])(转了一半从正变负的感觉。。)
于是这一部分DFT就可以递归计算了。
IDFT是DFT的逆,是解n个方程的线性方程组,现在知道(w,A(w))了,要求向量a。
令V为系数矩阵(由w们组成),令dij=wn-ij,d∈D,E=D·V,当i==j时,eij=n,否则为0(这个。。大佬的blog中的这个式子虽然推出来了,但是一时不知道为什么等于0,暂且一放),E为单位矩阵的n倍,即1/nD=V-1。原来的V·a = A 就可以变换为 a =1/nD·A,将上一部分的DFT中的wni变为wn-i再做一次之后除以n就是所求结果了。
conj()返回复共轭(记到小本本上) 打w表的时候把w-i一起打下来。
应用:快速卷积、生成函数运算、多项式除相关、多项式多点求值和快速插值
此处应当还有一块快速数论变换(FNT)来解决精度问题但现在没有_(:з」∠)_
可以求逆元了O(nlogn)
A(x)B(x)≡1(mod xn)&& deg B ≤ deg A 则 B(x)=A-1(x) (话说搜狗输入法说≡叫全等于,姑且当同余号用吧。。
当n==1时,A(x)≡c(mod x) A-1(x)==c-1;
当n>1时,设 A(x)B(x)≡1(modxn)
由 A(x)B'(x)≡1(mod x⌈n/2⌉) && A(x)B(x)≡1(mod x⌈n/2⌉) (将mod的数缩小到二分之一,可以类比为9%8和9%4的关系,仍成立)
相减可得 B(x)-B'(x)≡0(mod x⌈n/2⌉)
两边平方,模里的 x⌈n/2⌉ 也平方,意义为 mod xn为0的多项式其0到n-1项系数均为0,在多项式平方后,其0到2n-1项系数也均为0(某次数项的系数由小于等于其次数的项的系数组成),则mod平方后仍成立。
得到 B(x)≡2B'(x)−A(x)B'2(x) (mod xn) ,本式建立在n==1有解的前提下,即一个多项式在mod xn下是否有逆元取决于其常数项在mod xn下是否有逆元
现在,利用FFT/FNT递归把上式的多项式乘法算出来,就获得了B(x)啦。
应用:预处理Bernoulli数、计算有标号简单连通无向图个数
来除吧!
A(x)=D(x)B(x)+R(x) degD≤degA-degB(即n-m),degR<m
看起来要先消除掉R(x)才能开始除呢。首先,系数反转的方法:AR(x)=xnA(1/x)
将原式每一个多项式都视作最高次数(D为n-m,R为m-1,反正过高次的项系数视为0),然后全部反转,这个时候D(x)或者说目前的DR(x)本身的次数仍没有超过n-m,而R(x)与其前的xn-m+1整体的次数高于n-m(B和D前面的x可以凑在一起就可以和A前面的约掉)。根据mod的知识,这个时候只要mod一下xn-m+1,原式就会变成:
AR(x)=DR(x)BR(x) ( mod xn-m+1 )
然后来求逆元吧!求完之后再反转回来再代入求解R(x)
应用:多项式的扩展欧几里得、乘法逆元、多点求值
190723 ->实现代码要写的,后面的BM也要写的,但我需要站起来一会儿了_(:з」∠)_