zoukankan      html  css  js  c++  java
  • [学]从零(多项式基础与FFT)开始BM学习笔记

    好记性不如烂键盘|ू・ω・` )

    众所周知红小豆没有一点点数学基础,只好从爬出土开始

    只是个人的学习笔记,如果有什么地方不清楚可见下列神仙的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,,n1,可通过欧拉公式进行算术表示。

      用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])+ wn*Σ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])wn*Σa2i+1*wn/2ki(i∈[0,n/2-1])

              A(wnk+n/2)=Σa2i*wn/2ki(i∈[0,n/2-1])- wn*Σ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 =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 xn/2)  &&  A(x)B(x)1(mod xn/2) (将mod的数缩小到二分之一,可以类比为9%8和9%4的关系,仍成立)

          相减可得 B(x)-B'(x)≡0(mod xn/2)

          两边平方,模里的 xn/2 也平方,意义为 mod xn0的多项式其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也要写的,但我需要站起来一会儿了_(:з」∠)_

  • 相关阅读:
    java处理图片压缩、裁剪
    List按对象元素自定义排序
    List和数组汉字简单排序(转)
    欢迎访问我的个人博客,部分文章迁移
    Java资源免费分享,每日一更新,找到你心仪的吧
    今年的校招,Java好拿offer吗?
    【拥抱大厂系列】几个面试官常问的垃圾回收器,下次面试就拿这篇文章怼回去!
    2019,我的这一年,在校研究生做到年入20W,另送我的读者2000元现金红包
    深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析
    深入理解Java虚拟机-常用vm参数分析
  • 原文地址:https://www.cnblogs.com/non-/p/11234774.html
Copyright © 2011-2022 走看看