多项式运算的一些技术

昨天白天看了看多项式的一些东西,完全看不懂,于是晚上学一学多项式的基本运算。

以下用字母 \(f\) 表示多项式,带下标的字母表示系数 \(f_i\)\([n]\) 表示 \(\text{mod}~x^n\)

加减法

\[(f+g)(x)=\sum _{i=0}^\infty (f_i+g_i)x^i \]

直接加法是 \(O(n)\) 的。由上式也可以看出,点值之和是和的点值。

乘法

多项式意义下的乘法一般是线性卷积。

可以用叉乘表示,也可以简写

\[fg=(f\times g)(x)=\sum _k\sum _i\sum _j[i+j=k]f_ig_jx^k \]

\[(f\times g)_k=\sum _{i+j=k}f_ig_j \]

这可以用计算循环卷积的 fft 或 ntt 通过倍长实现线性卷积。

除法

\[\frac{f}{g}=f\times g^{-1} \]

问题就变成求一个多项式的逆元。

一个多项式是否有可能有一个完全的逆元呢?即一个多项式 \(f\) ,是否存在 \(g\) 使得 \((f\times g)(x)=1\)

对于次数大于 0 的多项式 \(f\) ,不存在有限长度的符合要求的 \(g\) ,因为 \(f\) 的最高次和 \(g\) 的最高次总是无法消掉的。

那么就讨论在有限的位中的逆元,因为一般我们要求的都是序列的前一些项,之后的是不需要考虑的。

问题变成了已知一个 \(g\) ,求 \(f\) 使得

\[\begin{aligned} fg\equiv 1 &&[n] \end{aligned} \]

即在 \(\text{mod}~x^n\) 的意义下求这个东西。

这类在对 \(x^k\) 取模意义下求的问题,一般用倍增解决。倍增的方式可以统一地用牛顿迭代得到。

设我们已经求出了 \(\text{mod}~x^\frac{n}{2}\) 的多项式 \(f_0\) ,拓展到 \(\text{mod}~x^n\)

设一个函数 \(H(x)\) ,为了方便计算,让它在对应解的位置取 0 。在这个问题中,\(H(x)=\frac{1}{x}-g\) ,这样对于符合要求的 \(f\) ,有 \(H(f)=\frac{1}{f}-g=g-g=0\)

\(f\) 处对 \(H\) 进行泰勒展开,用 \(f_0\) 来逼近它,可得

\[H(f)=\sum _{i=0}^\infty \frac{H^{(i)}(f_0)(f-f_0)^i}{i!} \]

这里有一个简单的结论:\(f\)\(f_0\) 的前 \(\frac{n}{2}\) 位是相同的。这是因为

\[\begin{aligned} f_0g\equiv 1&&[\frac{n}{2}] \\ fg\equiv 1 && [n] \\ (f-f_0)g\equiv 0 &&[\frac{n}{2}] \end{aligned} \]

\(g\ne 0\) ,得到结论。

也就是说,\((f-f_0)^2\) 的最低非 0 位至少在 \(x^n\) ,而我们要计算的是 \(\text{mod}~x^n\) 意义下的 \(f\) ,所以后面的项在当前是没有用的。

\[\begin{aligned} H(f)\equiv H(f_0)+H'(f_0)(f-f_0) && [n] \end{aligned} \]

由于我们要求的 \(f\)\(\text{mod}~x^n\) 的意义下,使得 \(H(f)=\frac{1}{f}-g=0\) ,所以有

\[\begin{aligned} H(f_0)+H'(f_0)(f-f_0)\equiv 0 && [n]\\ \end{aligned} \]

我们已经得到了解的一般形式。

\[\begin{aligned} f\equiv f_0-\frac{H(f_0)}{H'(f_0)} && [n] \end{aligned} \]

在上面的过程中 \(H\) 是一个抽象的,满足 \(H(f)\equiv 0 \mod x^n\) 的函数,它可以是任何函数。

代入我们这里的 \(H(x)=\frac{1}{x}-g\) ,并把 \(g\) 看作一个常量,那就有

\[\begin{aligned} f\equiv f_0-\frac{\frac{1}{f_0}-g}{-f_0^{-2}}&& [n] \\ f\equiv 2f_0-gf_0^2 && [n] \end{aligned} \]

它只涉及到递归求出 \(f_0\) 和长度为 \(n\) 的乘法,即复杂度为

\[T(n)=T(\frac{n}{2})+O(n\log n)=O(n\log n) \]

一个需要注意的地方:可以发现 \(f\) 的式子后面有 \(gf_0^2\) 这一项,意味着可能会出现多余的项,需要去掉。

由上述算法可以看出,多项式有模 \(x^n\) 意义下的逆元,等价于常数项有逆元。

乘方

快速幂+乘法方法,\(O(n\log ^2n)\)

也可以用下面讲到的方法做到 \(O(n\log n)\)

开根

即求 \(f\) 使得

\[\begin{aligned} f^k\equiv g && [n] \end{aligned} \]

运用上面的通用方法

\[\begin{aligned} f\equiv f_0-\frac{H(f_0)}{H'(f_0)} && [n] \end{aligned} \]

构造函数 \(H(x)=x^k-g\) ,展开可得

\[\begin{aligned} f&\equiv f_0-\frac{f_0^k-g}{kf_0^{k-1}} && [n] \\ f&\equiv \frac{k-1}{k}f_0+\frac{g}{kf_0^{k-1}} && [n] \end{aligned} \]

这里使用了乘法,加法和(除法)求逆,复杂度为 \(O(n\log ^2 n)\)

可以发现,多项式有模 \(x^n\) 意义下的根,等价于常数项有根。

可以用下面的方法做到 \(O(n\log n)\)

\(\exp \& \ln\)

终于到了这个时刻。

实数的开根和乘方,两种指数上的运算,可以用对数和指数的方法,变成加减法。多项式也如此。

对一个多项式 \(f\) ,定义 \(\exp f\) (即 \(e^f\) ),为泰勒展开的形式

\[\exp f=\sum _{k=0}^\infty \frac{f^k}{k!} \]

定义 \(\ln\)\(\exp\) 的逆运算,即 \(\ln (\exp f)=f\)

一般我们是不会需要上面的无穷形式的,而是需要得到前 \(n\) 位,所以求解仍然在 \(\text{mod}~x^n\) 意义下进行。

如何求这两个东西呢?

\(\ln\)

\[\begin{aligned} f\equiv \ln g && [n] \end{aligned} \]

对两边进行求导

\[\begin{aligned} f'\equiv \frac{g'}{g} && [n] \\ f\equiv \int \frac{g'}{g} && [n] \end{aligned} \]

多项式的求导和积分都是 \(O(n)\) 的,其中用到的逆元是 \(O(n\log n)\) 的,所以复杂度为 \(O(n\log n)\)

\(\exp\)

\(f\) 使得

\[\begin{aligned} \ln f\equiv g&& [n] \end{aligned} \]

运用通用方法,设 \(H(x)=\ln x-g\) ,那么

\[\begin{aligned} f&=f_0-\frac {H(f_0)}{H'(f_0)} && [n] \\ f&=f_0-\frac {\ln f_0-g}{\frac{1}{f_0}} && [n] \\ f&=f_0(1-\ln f_0+g) && [n] \end{aligned} \]

后记

大概就是这样啦

主要就是牛顿迭代倍增的方法和神奇的 \(\ln\)\(\exp\)

最近会做一些多项式相关的题,研究一下生成函数吧。

posted @ 2017-09-22 19:08  permui  阅读(779)  评论(0编辑  收藏  举报