多项式求逆
给定多项式 (F) ,求一个 (G) 使得 (F*Gequiv1 pmod {x^n})
多项式的模意义是指次数大于等于 (n) 的项都当成 (0),考虑倍增,设有多项式 (A) 满足 (F*Aequiv 1 pmod {x^{lceil{frac{n}2} ceil}}) ,上取整的意思为了让它平方后大于等于(n)的项都当成(0)。
显然有 (F*Gequiv1 pmod {x^{lceil{frac{n}2} ceil}}) ,根据模的定义可知。
所以有 (F*(G-A)equiv 0 pmod{x^{lceil{frac{n}2} ceil}}),(F) 不可能为 (0),于是 ((G-A)^2equiv0 pmod{x^n}),继续推一发,得到 (G^2-2AG+A^2equiv 0 pmod{x^n}),两边同时乘 (F) 得到 (G-2A+A^2Fequiv 0 pmod{x^n}),所以推出 (Gequiv 2A-A^2F),只有常数项的时候求逆元即可,分治即可求出。
多项式开根
求一个多项式 (F) 满足 (F^2=G),若 (F) 有两个,一般取正的。
仍然使用倍增,设 (F^2equiv Gpmod {x^{2n}}),假设已经求出了 (A^2equiv Gpmod {x^n}) ,那么有 (F^2-A^2equiv0 pmod {x^n}) 。
易得
在只有常数项的时候可以直接求出。
若常数项为 (1) 或 (0) ,开根后较为显然,但是有些毒瘤出题人并不喜欢简单,所以对于模意义下开根就比较重要 。
此时需要用到二次剩余
多项式除法
给定多项式 (F,G),求两个多项式 (A,B) 满足 (F=A*G+B) 。
其中 (F,G,A) 的项数分别为 (n,m,n-m),要求 (B) 的项数小于 (m)
定义一种变换,(F_{R(x)}=x^n F(frac{1}x)),容易发现这种变换就是将(F)的系数reverse了一下。
模一下 (x^{n-m+1}) 就能得到
多项式求逆即可。
多项式求导和积分
求导,([x^{i-1}]F'=[x^i]F imes i)
积分,积分是求导的逆运算,对一个多项式积分的结果表示哪个多项式求导得到的是这个多项式
([x^i]int F'=frac{[x^{i-1}]F'}i)。
多项式 (ln)
求一个多项式 (F) 满足 (G=ln F)
两边求导得到 (G'=ln'F F')
由(ln)的导数可以知道(ln'F=frac{1}F)
所以 (G'=frac{F'}F)
于是 (G=intfrac{F'}F)
多项式exp
令(G(x)equiv e^{f(x)}pmod {x^n},G_1(x)equiv e^{f(x)} pmod {x^{frac{n}2}})
有(Gequiv G_1(1-lnG_1+F) pmod {x^n})
证明略
上边的式子虽然易懂但是比较繁琐,因为对于不同的东西需要用到不同的式子,考虑更加通用的办法——牛顿迭代。
泰勒展开
对于一个函数 (F) , (F(x)) 的值可以近似看作在 (x_0) 处泰勒展开的值,即
这个式子看上去貌似到正无穷没有办法求,但是由于它递减的很快所以基本上只需要求前几项即可。
牛顿迭代
考虑如果求出了 (F(x) equiv 0 pmod {x^{lceilfrac{n}2 ceil}}) 的一个解 (x_0) ,如何求出另一个解 (x) 满足 (F(x) equiv 0 pmod {x^{n}}) 。
将 (F(x)) 在 (x_0) 处泰勒展开,容易得到
注意到后边写了省略号,并不是我懒得写了,而是因为没有用了,因为 (x) 和 (x_0) 在模 ({x^n}) 的意义下,前一半项是一样的,所以 (x-x_0) 的最低次项也是 (frac{n}2) 即大于 (2) 的次幂全是 (0) 。
于是有
这样推式子就简单的多了,更具体的,只需要构造一个函数 (F(x)equiv0 pmod {x^n}) 即可。
例如多项式乘法逆,构造函数 (F(x)=frac{1}x-G) ,其中 (G) 为给定的多项式 。
那么我们要求的实际上就是 (F(x)equiv0 pmod {x^n}) 的一个解。
直接代牛顿迭代,有
多项式开根,构造函数(F(x)=x^2-G) ,其中 (G) 为给定多项式。
代牛顿迭代,得到
简单易懂
任意模数多项式乘法
总有一些毒瘤出题人喜欢把模数搞得奇怪,让你没办法做 (NTT) ,这时候可以用 (CRT) ,但是常数过于大,就不大好玩 。
考虑一个古老的算法,其实也不是很古老,只是一段时间没怎么用过,(FFT) 。
因为 (FFT) 是不用取模的,所以可以直接乘然后最后一起取模,不过模数很大容易炸精,所以要拆系数,不妨令 ([x^i]F=a_0 imes T +b_0) ,然后分别求出(a,b)最后合并即可,即分别求出(a_0a_1,a_0b_1+a_1b_0,b_0b_1),这样做大概需要七次 (FFT) ,还是太慢了。
于是使用魔法,使得能够快速求出要求的几项。
令(P=a+bi,Q=a-bi),显然他们的系数是共轭的,有一个结论
(Q_0=P_0),其余的(Q_i=P_{n-i}),即(Q_i=P_{(n-1)&(n-i)}),所以只需要求出 (P),然后就有了 (Q),这样就把两次 (NTT) 合并成了一次 。此时再暴力求出剩下的几项只要五次,考虑继续优化。
令(A=a_0a_1+b_0b_1i,B=a_0b_1+a_1b_0),这样只需要做两次 (IDFT) 即可,所以就可以写出四次的 (MTT) 了。
多项式快速幂
给定多项式 (G), 求一个 (F) ,使得 (F=G^k)
比较好推,(ln F=kln G) ,(F=e^{kln G})
多项式复合
给定两个多项式 (F,G) ,求一个多项式(H(x)equiv F(G(x)) pmod {x^n})。
考虑暴力做,依次考虑 (G^i) 的贡献,与 (F) 的系数相乘后加入到答案里边,时间复杂度(O(n^2logn)),常数略大。
事实上没有必要把他们都乘出来
令(L=sqrt n),这样只需要预处理出(G^{iL},G^{i})即可,时间复杂度(O(n^2+nsqrt nlogn)),实际上 (n^2) 的部分常数比较小所以跑的飞快。
多项式复合逆
给定多项式 (G),求一个多项式 (F),使得 (G(F(x))=x) 。大概考虑一下这个东西有什么意义,比如有一个函数(H(G(x))=P(x)),那么代入复合逆就能够得到,(H(x)=P(F(x))),只需要多项式复合就能够求出 (H)。
拉格朗日反演
如果有(F(G(x))=x),即(F,G)互为复合逆,同时一定有(G(F(x))=x),可以称 (G(x)=F^{-1}(x)),(F(x)=G^{-1}(x))。
在这种情况下,有这样的式子:
可以 (nlogn) 的求出一项系数。
考虑
令(L=sqrt n),然后预处理一下后边的式子,可以 (O(n)) 求出两个多项式乘积的某一项,时间复杂度同上。
有标号连通图计数
考虑一个简单无向图的个数,显然是(2^{inom{i}{2}}),设其 (EGF) 为 (F)
一个无向图是由若干连通图拼在一起的,设连通图的 (EGF) 为 (G),枚举联通块个数,有
除掉阶乘是因为连通块之间没有区别。
所以(F=e^G),(G=ln F)
边双连通图计数
求大小为 (n) 的边双连通图的数量。
由于边双联通图没有一个固定的点,所以不大好做,考虑将其转化为有根的边双,其实就是加入了一个特殊点方便计数而已。
容易发现,设无根边双的 (EGF) 为 (P) ,有根边双为 (D),那么 (D_i=iP_i),原因是每个点都成为过根。
考虑有根边双怎么求,一张有根连通图一定是由若干个边双联通分量构成的,考虑根所在的边双联通分量,除去这个边双联通分量后,原图一定会分为若干个有根联通图,枚举根所在的连通分量的大小和划分成的有根连通图的个数,设有根联通图的 (EGF)为 (F),有
由
所以
(F) 显然比较好求,考虑(D) 怎么求,令(H=xe^F),有(F(x)=D(H(x))),两边同时带入 (H) 的复合逆,有,(F(H^{-1}(x))=D(x))。
所以只需要求出(F(H^{-1})),由拉格朗日反演
代入(H=xe^F),有
于是可以 (nlogn) 求出 (D) 的一项。
多项式多点求值
给定一个 (n) 次多项式和 (m) 个值,求出 (F(a_1),F(a_2),……F(a_m)) 。
构造两个多项式(P=prod_{i=1}^{frac{n}2}(x-a_i),Q=prod_{i=frac{n}2+1}^n(x-a_i)),那么如果令(F=P*A+B),对于任意 ([1,frac{n}2]) 中的点,(F(a_i)=B(a_i)),原因是代入后 (P) 为 (0),所以就有了理论上是 (nlogn) 实际上有大常数的多项式取模写法。
实际上取模的做法貌似已经成了时代的眼泪,我们现在已经有了更快的转置做法。
考虑一种减法卷积,定义 (c=Mult(a,b)) 即 (c_i=sum_{j=0}^{+infty}a_jb_{j-i})。
它有一个性质是,(Mult(Mult(a,b),c)=Mult(a,b*c)),可以利用这个性质进行多点求值。
将 (F(a_j)) 展开,得到
观察发现,如果构造一个多项式 (G_j=sum_{i=0}^{n}a_j^ix^i),那么 $ F(a_j) $ 实际上是 (Mult(F,G_j)) 的常数项,证明很简单,代入即可。
(G) 是一个 (n) 次的多项式,暴力做的话是 (nmlogn) ,不如直接乘,考虑优化,将 (G) 写成封闭形式,(G_j=frac{1}{1-a_jx}),这样就可以 (O(1)) 的算出每一个 (G_j) 的分母,但是还是没啥用,因为乘起来还是要 (O(nlogn)) ,最后我们要的是每一个 (Mult(F,G_j)) 的常数项,考虑求出 (prod_{j=1}^mG_j),可以用分治乘法和求逆求出,直接令(F=Mult(F,prod_{j=1}^mG_j)),再一次进行分治,如果进去左区间就把右区间的贡献去掉,具体的,设 (T=prod_{j=frac{n}2+1}^{n}frac{1}{G_j}),只需要令 (F=Mult(F,T)),进入右区间时同理,原因是暴力做是对于右区间的每一个 (j),进行 (Mult(Mult(F,frac{1}{G_j}),frac{1}{G_j})),由 (Mult(Mult(a,b),c)=Mult(a,b*c)) 知,可以先对右区间卷积起来一起做减法卷积。
然后就有了小常数的多点求值。
多项式快速插值
给定 (n+1) 个点值,要求一个 (n) 次多项式。
考虑拉格朗日插值法,有
这个式子为什么是对的,其实很简单,发现带入任意 (x_i) 都成立,然后就没了。
但是直接做是 (O(n^2)) 的,将其进行简单变形。
考虑带有 (y_i) 的那一项,容易发现只需要求出下边的即可,有点难求于是构造一个多项式 (G=prod_{i=0}^nx-x_i),只需要求出 (frac{G(x)}{x-x_i}),这个东西看起来好求但是实际上不是很好玩,因为分子分母在(x=x_i)的时候都是(0)。
这时候就要用到洛必达法则了。
众所周知,两个无穷小之比或两个无穷大之比的极限可能存在,也可能不存在。因此,求这类极限时往往需要适当的变形,转化成可利用极限运算法则或重要极限的形式进行计算。洛必达法则便是应用于这类极限计算的通用方法 。
洛必达法则:对于 (frac{f(x)}{g(x)}),若(limlimits_{x→a}f(x)=0,limlimits_{x→a}g(x)=0),那么(limlimits_{x→a}frac{f(x)}{g(x)}=limlimits_{x→a}frac{f'(x)}{g'(x)}) 。
也就是说,当 (x=x_i) 时,$frac{G(x)}{x-x_i}=frac{G'(x)}{(x-x_i)'}=G'(x) $
于是有,
使用多项式多点求值即可求出所有的 (G') ,不妨令 (y_i=frac{y_i}{G'(x_i)})。
那么实际上要求的是
令
直接暴力拆开,
自底向上乘即可。
下降幂多项式乘法
给定下降幂多项式 (F,G),求 (F*G)。
首先考虑一个下降幂单项式 (x^{underline n}) 的点值 (EGF)
即 (e^xx^{n}) ,那么只需要将 (F,G) 乘上 (e^x) 即可转化为点值的 (EGF) ,之后直接用点值相乘即可,注意得到的是点值的 (EGF) 所以相乘的时候要乘上一个阶乘。
下降幂多项式转普通多项式
给定一个下降幂多项式,求一个与其相等的普通多项式。
直接将下降幂转化成点值的形式然后快速插值即可。
普通多项式转下降幂多项式
给定一个普通多项式,求一个与其相等的下降幂多项式。
使用多点求值求出下降幂的点值 (EGF) ,然后乘上 (e^{-x}) 即可。