「笔记」多项式乱写


没什么干货,基本上都是瞎写,而且是想到什么写什么,所以可能你看完也学习不到什么。

由于我数学很差,所以可能会写大堆废话 + 大堆错误 + 大堆不带证明的结论。

对之前多项式(生成函数)相关内容做个整理,之前的垃圾博客都隐藏了。

由于我水平有限,所以写的东西比较显然,内容也十分基础入门。

大部分算法只限于口胡而没有实现过,所以不保证正确性。


请问生成函数该怎么定义啊.jpg

如果按照函数去理解,你会发现我们几乎没有管敛散性,然而这并不严谨。

如果按照形式幂级数的方式去定义,你需要手动验证如 \(\exp,\ln,\int,\frac{dy}{dx}\) 满足它们该有的性质(尽管来说这是可以做到的,丢一个链接就逃)。

放弃思考它的正确性,感觉该怎么做就怎么做吧。


mtt

不太想再写一遍 fft 相关教程,就写个 mtt 的做法吧。

\(S = \lfloor\sqrt{M}\rfloor\),可以把系数 \(a_i\) 拆成 \(\lfloor\frac{a_i}{S}\rfloor\)\(a_i \bmod S\),这样正变换四次,逆变换三次即可,且精度也有保证。

将两次正变换缩成一次的优化:如果当前有两个实系数多项式 \(A(x), B(x)\) 要正变换,可以转化成 \(P(x)=A(x)+iB(x),Q(x) =A-iB(x)\) 正变换。

考虑可否知 \(Q\)\(P\)(以下记 \(\overline{z}\) 表示 \(z\) 的共轭,记 \(\hat{Q}_j\) 表示 \(Q(\omega_{n}^{j})\)):

\[\hat Q_j=\sum_{k=0}^{n-1}(a_k-ib_k)\times\omega_{n}^{jk} = \sum_{k=0}^{n-1}\overline{(a_k+ib_k)}\times\overline{\omega_{n}^{(n-j)k}} =\sum_{k=0}^{n-1}\overline{(a_k+ib_k)\times \omega_{n}^{(n-j)k}}=\overline{\hat P_{n-j}} \]

然后考虑逆变换是否也可以两次缩一次:\(\hat R_j = \hat A_j + i\hat B_j\),则逆变换后 \(r_j = a_j + ib_j\)。由于 \(A(x),B(x)\) 都是实系数,所以直接取实虚部对应系数即可。

这样的话只需做 4 次(严格来说只需做 3.5 次——假如你需要做多次卷积,可以把单出来的逆变换放一起做)。


牛顿迭代

事实上,牛顿迭代一般是用来解方程的数值解而非方程的封闭解。

attention:以下记 \(z\) 为形式幂级数的元,记 \(x\)\(z\) 的幂级数(即 \(x = f(z)\),其中 \(f\) 是个多项式)。

解方程 \(F(x)=0\)(一般来说是在 \(\bmod z^{n}\) 意义下),基础思想为倍增,即根据 \(\bmod z^n\) 的解 \(x_0\) 求出 \(\bmod z^{2n}\) 的解 \(x\)

注意到 \(x = x_0 \bmod z^n\),因此有 \((x-x_0)^2 = 0\bmod z^{2n}\),也即 \((x-x_0)^k=0\bmod z^{2n},k>1\)

考虑将 \(F(x)\)\(x_0\) 处泰勒展开得 \(F(x) = \sum_{i=0}^{\infin}\frac{F^{(i)}(x_0)}{i!}(x-x_0)^i=0\bmod z^{2n}\)。注意这里的求导是对 \(x\) 求导,因此会有 \(\frac{dA(z)}{dx}=0\)

由上可知 \(F(x) = F(x_0) + F'(x_0)(x-x_0)=0\bmod z^{2n}\),变形得到 \(x=x_0-\frac{F(x_0)}{F'(x_0)} \bmod z^{2n}\)(即牛顿迭代的式子)。

这里的复杂度瓶颈在于计算 \(\frac{F(x_0)}{F'(x_0)}\)(实际上在做多项式复合)。


几个经典应用:

(1)求逆,即解方程 \(F(x) = \frac{1}{x} - A(z) = 0\)(方程 \(A(z)x-1=0\) 虽然也正确,但是用牛迭解不出来),牛迭式为 \(x=2x_0-A(z)x_0^2\)

(2)求 \(\ln\)(尽管它并不是用牛迭做),\(\ln A(z)=\int \frac{A'(z)}{A(z)}dz\),求逆即可。

(3)求 \(\exp\),即解方程 \(\ln x - A(z)=0\),牛迭式为 \(x=x_0-(\ln x_0-A(z))x_0\)

(4)求幂,\(A^k(z)=\exp(k\times\ln A(z))\)(如果多项式系数是在模意义下运算,\(k\) 直接对模数取模——这里和费马小定理/欧拉定理扯不上关系)。

(5)求一阶微分方程,即解方程 \(\frac{dx}{dz}=F(x)\)(其实这个难点主要在于微积分的技巧),牛迭到某一步时有 \(\frac{dx}{dz}=F(x_0)+F'(x_0)(x-x_0)\bmod z^{2n}\)

即解方程 \(\frac{dx}{dz}-F'(x_0)x=F(x_0)-F'(x_0)x_0\)接着随便翻开本微积分教材 构造 \(P(x_0) = e^{\int F'(x_0)dz}\)(还是注意这里的 \(F'(x_0)\) 是对 \(x\) 求导):

\[\begin{aligned} \frac{dx}{dz}-xF'(x_0)=\frac{1}{P(x_0)}\left(\frac{dx}{dz}P(x_0)- xF'(x_0)P(x_0)\right)=\frac{1}{P(x_0)}\frac{d(xP(x_0))}{dz} \end{aligned} \]

而等式右边是常数,就可以继续解了。

以上例子时间复杂度都是 \(O(\sum_{i=0}\frac{n}{2^i}\log \frac{n}{2^i}) = O(n\log n)\)


拉格朗日反演

attention:以下记 \(z\) 为形式幂级数的元,记 \(x\)\(z\) 的幂级数(即 \(x = f(z)\),其中 \(f\) 是个多项式)。

attention:以下记 \(F^{-1}(z)\)\(F(z)\) 的复合逆,而将 \(F(z)\) 的乘法逆写作 \(\frac{1}{F(z)}\)

我们只考虑常数项为 0,一次项为 1 的形式幂级数,这些幂级数在复合运算下形成群,所以 \(\forall F(z),\exist F^{-1}(z),F^{-1}(F(z)) = F(F^{-1}(z)) = z\)

求复合逆 \(F^{-1}(z)\) 可以根据定义列方程牛顿迭代,或者参考下面 “多项式复合” 部分。当然一般来说,最常用的是拉格朗日反演。

先说明,我们将形式幂级数的环扩成了分式环,所以才能定义出常数项为 0 的幂级数的乘法逆,如 \(z^{-1}\)

拉格朗日反演告诉我们 \([z^n]F^{-1}(z)=\frac{1}{n}[z^{-1}](\frac{1}{F^n(z)})\),有一个更常用的形式是 \([z^n]F^{-1}(z)=\frac{1}{n}[z^{n-1}](\frac{z}{F^n(z)})\)

扩展拉格朗日反演告诉我们 \([z^n]H(F^{-1}(z)) = \frac{1}{n}[z^{-1}]H'(z)(\frac{1}{F^n(z)})\),同上,更常用的形式是 \([z^n]H(F^{-1}(z)) = \frac{1}{n}[z^{n-1}]H'(z)(\frac{z}{F^n(z)})^n\)

证明:

\(F^{-1}(z)=\sum a_iz^i\),则 \(\sum a_i F^i(z) = z\)

两边对 \(z\) 求导,得 \(\sum ia_i F^{i-1}(z)F'(z)=1\)

两边同除以 \(F^n(z)\),得 \(\sum a_i F^{i-n-1}(z)F'(z)=\frac{1}{F^n(z)}\)

\(i\not = n\) 时,\([x^{-1}]ia_iF^{i-n-1}(z)F'(z)=[x^{-1}]\frac{ia_i}{i-n}(F^{i-n})'(x)=0\)(幂函数求导不可能出现 \(x^{-1}\))。

\(i = n\) 时,\([x^{-1}]na_n\frac{F'(z)}{F(z)}=[x^{-1}]na_n\frac{F'(z)}{z}\times\frac{z}{F(z)}=na_n\)(注意 \(F(z)\) 常数项为 0 且一次项为 1)。

因此有 \(a_n=\frac{1}{n}[x^{-1}]\frac{1}{F^n(z)}\)。扩展形式基本一样,只是把一开始等式右边的 \(z\) 替换成了 \(H(z)\)

考虑对二元函数 \([z^n](\frac{1}{1-uF(z)})\) 作拉格朗日反演得到 \(\frac{1}{n}[z^{n-1}](\frac{1}{1-uz})'(\frac{z}{F^{-1}(z)})^n\)

左边即 \([z^n]F(z), [z^n]F^2(z),\dots [z^n]F^n(z)\)。如果复合逆很好求,那么就可以快速算出前面的东西。

据说很有用。


杂项

带余除法

请问为什么要对 “带鱼” 做除法。

形式幂级数是欧式环 \(\Leftrightarrow\) 形式幂级数可做带余除法。

\(F(x)=\sum_{i=0}^{n-1}f_ix^i\),则记 \(degF=n-1\)

给定 \(A(x), B(x)\),我们想找到 \(P(x),R(x)\) 满足 \(degR<degB\)\(A(x)=B(x)P(x) + R(x)\)。可以发现此时有 \(degP=degA-degB\)

考虑变换 \(A_r(x) = x^{degA}A(x^{-1})\),即把 \(A\) 的系数翻转得到 \(A_r(x)\)

对上述等式做该变换得到 \(A_r(x)=B_r(x)P_r(x)+R_r(x)x^{degA-degB+1}\),对 \(x^{degA-degB+1}\) 取模转化成多项式求逆,求出 \(P(x)\) 后作减法即得 \(R(x)\)


多点求值(旧)

如果想对 \(x_1,x_2\dots x_n\) 求值,可以分治先算出 \(P_L(x)=\prod_{i=1}^{mid}(x-x_i)\)\(P_R(x)=\prod_{i=mid+1}^{n}(x-x_i)\)

由于 \(\forall i\in[1,mid],P_L(x_i)=0\),所以 \(\forall i\in[1,mid],A(x_i) = (A \bmod P_L)(x_i)\),同理 \(\forall i\in[mid+1,n],A(x_i)=(A\bmod P_R)(x_i)\)

于是分治即可,时间复杂度 \(O(n\log^2 n)\)

一个小应用:求范德蒙行列式 \(\prod_{1\leq j < i \leq n}(x_i-x_j)\)

\(F_i(x)=\prod_{j=1}^{i-1}(x-x_j)\),则答案为 \(\prod F_i(x_i)\)。可以发现多点求值在递归时可以顺便算出 \(F_i(x)\)


快速插值

从拉格朗日插值入手优化:\(F(x)=\sum_{i=1}^{n} y_i\times\frac{\prod_{j=1,j\not=i}^{n}(x-x_j)}{\prod_{j=1,j\not=i}^{m}(x_i-x_j)}\)

首先考虑求出 \(k_i=\prod_{j=1,j\not=i}^{n}(x_i-x_j) = \lim_{x\to x_i}\frac{\prod_{j=1}^{n}(x_i-x_j)}{x-x_i}\)。记 \(G(x)=\prod_{j=1}^{n}(x-x_j)\),洛必达一下得 \(k_i=G'(x_i)\),多点求值即可。

考虑 \(F(x)=\sum_{i=1}^{n}\frac{y_i}{v_i}\prod_{j=1,j\not = i}^{n}(x-x_j)\),可以考虑类 cdq 分治的方法求,即 \(F(x)=F_L(x)P_R(x)+F_R(x)P_L(x)\)(这里的 \(P\) 和上面的多点求值是同一定义)。


多点求值(新)

转置原理是个啥啊,算了不管了。

“然而 $E在此基础上加了很多优化,所以他可以 5e5 多点求值。”——《$E为什么可以5e5多点求值(详细揭秘)

attention:以下的记法并不严谨,仅作为个人学习的辅助记法。

一般的卷积定义为 \(f_{i+j}=\sum g_ih_j\),用形式幂级数记为 \(F(x) = G(x)\cdot H(x)\)

我们定义另一种 “卷积“ \(f_{i-j}=\sum g_ih_j\),用形式幂级数记为 \(F(x)=G(x)\times H(x)\)(注意它其实并不交换也不结合,所以不能算真正的卷积)。

那么有 \(F(a) = [x^0](F(x)\times\frac{1}{1-ax})\),将求值问题转化成了 “卷积” 问题。

注意到 \(F(x)\times(G(x)\cdot H(x)) = (F(x)\times G(x))\times H(x)\)(根据定义,这是显然的)。

一样考虑分治,尝试根据 \(F(x)\times(\prod_{i=l}^{r}\frac{1}{1-a_ix})\) 求出 \(F(x)\times(\prod_{i=l}^{mid}\frac{1}{1-a_ix})\)\(F(x)\times(\prod_{i=mid+1}^{r}\frac{1}{1-a_ix})\),根据上面那条性质算即可。

由于我们只需要求 \(x^0\) 的系数,所以分治时可以只保留有用的项,因此时间复杂度 \(O(n\log ^2 n)\)(然而这个方法只需要一次求逆得到 \(\prod_{i=1}^{n}\frac{1}{1-a_ix}\))。

其他应用可以看今年WC的员交课件?


多项式复合

目前最优复杂度可以做 \(O((n\log n)^{1.5})\),然而我不会,所以咕掉了。

复合即是给定 \(F(x)=\sum f_i x^i, G(x)=\sum g_i x^i\),求 \(\sum f_i G^i(x)\)

有一个比较好的替代复杂度为 \(O(n^2+n\sqrt{n}\log n)\)

类似 BSGS,我们处理出 \(G^{i\times\sqrt{n}}(x)\)\(G^i(x)\) 的 dft,然后 \(O(n^2)\) 暴力乘并卷回去。

复合逆也可以结合拉格朗日反演公式 + 分块做到 \(O(n^2 + n\sqrt{n}\log n)\)

posted @ 2020-08-01 16:42  Tiw_Air_OAO  阅读(8)  评论(0编辑  收藏