多项式

多项式求逆

给定多项式 \(F\) ,求一个 \(G\) 使得 \(F*G\equiv1 \pmod {x^n}\)

多项式的模意义是指次数大于等于 \(n\) 的项都当成 \(0\),考虑倍增,设有多项式 \(A\) 满足 \(F*A\equiv 1 \pmod {x^{\lceil{\frac{n}2}\rceil}}\) ,上取整的意思为了让它平方后大于等于\(n\)的项都当成\(0\)

显然有 \(F*G\equiv1 \pmod {x^{\lceil{\frac{n}2}\rceil}}\) ,根据模的定义可知。

所以有 \(F*(G-A)\equiv 0 \pmod{x^{\lceil{\frac{n}2}\rceil}}\)\(F\) 不可能为 \(0\),于是 \((G-A)^2\equiv0 \pmod{x^n}\),继续推一发,得到 \(G^2-2AG+A^2\equiv 0 \pmod{x^n}\),两边同时乘 \(F\) 得到 \(G-2A+A^2F\equiv 0 \pmod{x^n}\),所以推出 \(G\equiv 2A-A^2F\),只有常数项的时候求逆元即可,分治即可求出。

多项式开根

求一个多项式 \(F\) 满足 \(F^2=G\),若 \(F\) 有两个,一般取正的。

仍然使用倍增,设 \(F^2\equiv G\pmod {x^{2n}}\),假设已经求出了 \(A^2\equiv G\pmod {x^n}\) ,那么有 \(F^2-A^2\equiv0 \pmod {x^n}\)

易得

\[(F+A)(F-A)\equiv0 \pmod {x^n} \]

\[(F-A)\equiv0 \pmod {x^n} \]

\[(F-A)^2\equiv0 \pmod {x^{2n}} \]

\[F^2+A^2-2AF\equiv0 \pmod {x^{2n}} \]

\[G+A^2-2AF\equiv0 \pmod {x^{2n}} \]

\[F\equiv \frac{G+A^2}{2A}\pmod {x^{2n}} \]

在只有常数项的时候可以直接求出。

若常数项为 \(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了一下。

\[F=A*G+B \]

\[F(\frac{1}x)=A(\frac{1}x)G(\frac{1}x)+B(\frac{1}x) \]

\[x^nF(\frac{1}x)=x^nA(\frac{1}x)G(\frac{1}x)+x^nB(\frac{1}x) \]

\[x^nF(\frac{1}x)=x^{n-m}A(\frac{1}x)x^mG(\frac{1}x)+x^{n-m+1}x^{m-1}B(\frac{1}x) \]

\[F_{R(x)}=A_{R(x)}G_{R(x)}+x^{n-m+1}B_{R(x)} \]

模一下 \(x^{n-m+1}\) 就能得到

\[F_{R(x)}\equiv A_{R(x)}G_{R(x)} \pmod {x^{n-m+1}} \]

\[A_{R(x)}\equiv F_{R(x)}G^{-1}_{R(x)} \pmod {x^{n-m+1}} \]

多项式求逆即可。

多项式求导和积分

求导,\([x^{i-1}]F'=[x^i]F\times 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=\int\frac{F'}F\)

多项式exp

\(G(x)\equiv e^{f(x)}\pmod {x^n},G_1(x)\equiv e^{f(x)} \pmod {x^{\frac{n}2}}\)

\(G\equiv G_1(1-lnG_1+F) \pmod {x^n}\)

证明略

上边的式子虽然易懂但是比较繁琐,因为对于不同的东西需要用到不同的式子,考虑更加通用的办法——牛顿迭代。

泰勒展开

对于一个函数 \(F\)\(F(x)\) 的值可以近似看作在 \(x_0\) 处泰勒展开的值,即

\[F(x)=\sum_{i=0}^{+\infty} \frac{F^{(i)}_{x_0}(x-x_0)^i}{i!} \]

这个式子看上去貌似到正无穷没有办法求,但是由于它递减的很快所以基本上只需要求前几项即可。

牛顿迭代

考虑如果求出了 \(F(x) \equiv 0 \pmod {x^{\lceil\frac{n}2\rceil}}\) 的一个解 \(x_0\) ,如何求出另一个解 \(x\) 满足 \(F(x) \equiv 0 \pmod {x^{n}}\)

\(F(x)\)\(x_0\) 处泰勒展开,容易得到

\[F(x)=F_{x_0}+F'_{x_0}(x-x_0)+.... \]

注意到后边写了省略号,并不是我懒得写了,而是因为没有用了,因为 \(x\)\(x_0\) 在模 \({x^n}\) 的意义下,前一半项是一样的,所以 \(x-x_0\) 的最低次项也是 \(\frac{n}2\) 即大于 \(2\) 的次幂全是 \(0\)

于是有

\[F_{x_0}+F'_{x_0}(x-x_0) \equiv 0 \pmod {x^n} \]

\[F'_{x_0}x\equiv F'_{x_0}x_0-F_{x_0} \pmod {x^n} \]

\[x\equiv x_0-\frac{F_{x_0}}{F'_{x_0}} \pmod {x^n} \]

这样推式子就简单的多了,更具体的,只需要构造一个函数 \(F(x)\equiv0 \pmod {x^n}\) 即可。

例如多项式乘法逆,构造函数 \(F(x)=\frac{1}x-G\) ,其中 \(G\) 为给定的多项式 。

那么我们要求的实际上就是 \(F(x)\equiv0 \pmod {x^n}\) 的一个解。

直接代牛顿迭代,有

\[x\equiv x_0 - \frac{\frac{1}{x_0}-G}{-\frac{1}{x_0^2}} \pmod {x^n} \]

\[x\equiv 2x_0-Gx_0^2 \pmod {x^n} \]

多项式开根,构造函数\(F(x)=x^2-G\) ,其中 \(G\) 为给定多项式。

代牛顿迭代,得到

\[x\equiv x_0-\frac{x_0^2-G}{2x_0} \pmod {x^n} \]

\[x\equiv \frac{x_0^2+G}{2x_0} \pmod {x^n} \]

简单易懂

任意模数多项式乘法

总有一些毒瘤出题人喜欢把模数搞得奇怪,让你没办法做 \(NTT\) ,这时候可以用 \(CRT\) ,但是常数过于大,就不大好玩 。

考虑一个古老的算法,其实也不是很古老,只是一段时间没怎么用过,\(FFT\)

因为 \(FFT\) 是不用取模的,所以可以直接乘然后最后一起取模,不过模数很大容易炸精,所以要拆系数,不妨令 \([x^i]F=a_0\times 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=k\ln G\) ,\(F=e^{k\ln G}\)

多项式复合

给定两个多项式 \(F,G\) ,求一个多项式\(H(x)\equiv F(G(x)) \pmod {x^n}\)

考虑暴力做,依次考虑 \(G^i\) 的贡献,与 \(F\) 的系数相乘后加入到答案里边,时间复杂度\(O(n^2logn)\),常数略大。

事实上没有必要把他们都乘出来

\[H=\sum_{i=0}^{n-1}[x^i]FG^i \]

\[H=\sum_{i=0}^{L}\sum_{j=0}^{L-1}[x^{iL+j}]FG^{iL+j} \]

\[H=\sum_{i=0}^{L}G^{iL}\sum_{j=0}^{L-1}[x^{iL+j}]FG^{j} \]

\(L=\sqrt n\),这样只需要预处理出\(G^{iL},G^{i}\)即可,时间复杂度\(O(n^2+n\sqrt 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)\)

在这种情况下,有这样的式子:

\[[x^n]F(x)=\frac{1}n[x^{n-1}](\frac{x}{G(x)})^n \]

\[[x^n]H(F(x))=\frac{1}n[x^{n-1}]H'(x)(\frac{x}{G(x)})^n \]

可以 \(nlogn\) 的求出一项系数。

考虑

\[F=\sum_{i=1}^{n}\frac{1}i[x^{i-1}](\frac{x}{G(x)})^i \]

\[F=\sum_{i=0}^{L}\sum_{j=1}^{L}\frac{1}{iL+j}[x^{iL+j-1}](\frac{x}{G(x)})^{iL+j} \]

\[F=\sum_{i=0}^{L}\sum_{j=1}^{L}\frac{1}{iL+j}[x^{iL+j-1}](\frac{x}{G(x)})^{iL}(\frac{x}{G(x)})^{j} \]

\(L=\sqrt n\),然后预处理一下后边的式子,可以 \(O(n)\) 求出两个多项式乘积的某一项,时间复杂度同上。

有标号连通图计数

考虑一个简单无向图的个数,显然是\(2^{\binom{i}{2}}\),设其 \(EGF\)\(F\)

一个无向图是由若干连通图拼在一起的,设连通图的 \(EGF\)\(G\),枚举联通块个数,有

\[F=\sum_{i=0}^{+\infty}\frac{G^i}{i!} \]

除掉阶乘是因为连通块之间没有区别。

所以\(F=e^G\)\(G=\ln F\)

边双连通图计数

求大小为 \(n\) 的边双连通图的数量。

由于边双联通图没有一个固定的点,所以不大好做,考虑将其转化为有根的边双,其实就是加入了一个特殊点方便计数而已。

容易发现,设无根边双的 \(EGF\)\(P\) ,有根边双为 \(D\),那么 \(D_i=iP_i\),原因是每个点都成为过根。

考虑有根边双怎么求,一张有根连通图一定是由若干个边双联通分量构成的,考虑根所在的边双联通分量,除去这个边双联通分量后,原图一定会分为若干个有根联通图,枚举根所在的连通分量的大小和划分成的有根连通图的个数,设有根联通图的 \(EGF\)\(F\),有

\[F=\sum_{i=1}^{+\infty}\frac{D_ix^i\sum_{j=0}^{+\infty}\frac{F^ji^j}{j!}}{i!} \]

\[\frac{F^ji^j}{j!}=\frac{(Fi)^j}{j!}=e^{Fi} \]

所以

\[F=D(xe^F) \]

\(F\) 显然比较好求,考虑\(D\) 怎么求,令\(H=xe^F\),有\(F(x)=D(H(x))\),两边同时带入 \(H\) 的复合逆,有,\(F(H^{-1}(x))=D(x)\)

所以只需要求出\(F(H^{-1})\),由拉格朗日反演

\[[x^i]F(H^{-1})=\frac{1}i[x^{i-1}]F'(\frac{x}{H})^i \]

代入\(H=xe^F\),有

\[[x^i]F(H^{-1})=\frac{1}i[x^{i-1}]F'e^{-iF} \]

于是可以 \(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)\) 展开,得到

\[F(a_j)=\sum_{i=0}^{n}[x_i]Fa_j^i \]

观察发现,如果构造一个多项式 \(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\) 次多项式。

考虑拉格朗日插值法,有

\[F=\sum_{i=0}^ny_i\prod_{i!=j}\frac{x-x_j}{x_i-x_j} \]

这个式子为什么是对的,其实很简单,发现带入任意 \(x_i\) 都成立,然后就没了。

但是直接做是 \(O(n^2)\) 的,将其进行简单变形。

\[F=\sum_{i=0}^n\frac{y_i}{\prod_{i!=j}x_i-x_j}\prod_{i!=j}{x-x_j} \]

考虑带有 \(y_i\) 的那一项,容易发现只需要求出下边的即可,有点难求于是构造一个多项式 \(G=\prod_{i=0}^nx-x_i\),只需要求出 \(\frac{G(x)}{x-x_i}\),这个东西看起来好求但是实际上不是很好玩,因为分子分母在\(x=x_i\)的时候都是\(0\)

这时候就要用到洛必达法则了。

众所周知,两个无穷小之比或两个无穷大之比的极限可能存在,也可能不存在。因此,求这类极限时往往需要适当的变形,转化成可利用极限运算法则或重要极限的形式进行计算。洛必达法则便是应用于这类极限计算的通用方法 。

洛必达法则:对于 \(\frac{f(x)}{g(x)}\),若\(\lim\limits_{x→a}f(x)=0,\lim\limits_{x→a}g(x)=0\),那么\(\lim\limits_{x→a}\frac{f(x)}{g(x)}=\lim\limits_{x→a}\frac{f'(x)}{g'(x)}\)

也就是说,当 \(x=x_i\) 时,$\frac{G(x)}{x-x_i}=\frac{G'(x)}{(x-x_i)'}=G'(x) $

于是有,

\[F=\sum_{i=0}^n\frac{y_i}{G'(x_i)}\prod_{i!=j}{x-x_j} \]

使用多项式多点求值即可求出所有的 \(G'\) ,不妨令 \(y_i=\frac{y_i}{G'(x_i)}\)

那么实际上要求的是

\[F=\sum_{i=0}^ny_i\prod_{i!=j}{x-x_j} \]

\[F_{l,r}=\sum_{i=l}^ry_i\prod_{i!=j}{x-x_j} \]

直接暴力拆开,

\[F_{l,r}=\sum_{i=l}^{mid}y_i\prod_{i!=j}{x-x_j}+\sum_{i=mid+1}^ry_i\prod_{i!=j}{x-x_j} \]

\[F_{l,r}=\sum_{i=l}^{mid}y_i\prod_{i=l,i!=j}^{mid}{x-x_j}\prod_{i=mid+1}^nx-x_j+\sum_{i=mid+1}^ry_i\prod_{i=mid+1,i!=j}^n{x-x_j}\prod_{i=l}^{mid}x-x_j \]

\[F_{l,r}=F_{l,mid}\prod_{i=mid+1}^nx-x_j+F_{mid+1,r}\prod_{i=l}^{mid}x-x_j \]

自底向上乘即可。

下降幂多项式乘法

给定下降幂多项式 \(F,G\),求 \(F*G\)

首先考虑一个下降幂单项式 \(x^{\underline n}\) 的点值 \(EGF\)

\[\sum_{i=n}^{+\infty}\frac{i^\underline n}{i!}x^i \]

\[\sum_{i=n}^{+\infty}\frac{1}{(i-n)!}x^i \]

\[\sum_{i=0}^{+\infty}\frac{1}{i!}x^{i+n} \]

\(e^xx^{n}\) ,那么只需要将 \(F,G\) 乘上 \(e^x\) 即可转化为点值的 \(EGF\) ,之后直接用点值相乘即可,注意得到的是点值的 \(EGF\) 所以相乘的时候要乘上一个阶乘。

下降幂多项式转普通多项式

给定一个下降幂多项式,求一个与其相等的普通多项式。

直接将下降幂转化成点值的形式然后快速插值即可。

普通多项式转下降幂多项式

给定一个普通多项式,求一个与其相等的下降幂多项式。

使用多点求值求出下降幂的点值 \(EGF\) ,然后乘上 \(e^{-x}\) 即可。

posted @ 2021-02-02 08:11  An_Fly  阅读(253)  评论(4编辑  收藏  举报