多项式运算的一些技术
昨天白天看了看多项式的一些东西,完全看不懂,于是晚上学一学多项式的基本运算。
以下用字母 \(f\) 表示多项式,带下标的字母表示系数 \(f_i\) ,\([n]\) 表示 \(\text{mod}~x^n\) 。
加减法
直接加法是 \(O(n)\) 的。由上式也可以看出,点值之和是和的点值。
乘法
多项式意义下的乘法一般是线性卷积。
可以用叉乘表示,也可以简写
即
这可以用计算循环卷积的 fft 或 ntt 通过倍长实现线性卷积。
除法
问题就变成求一个多项式的逆元。
一个多项式是否有可能有一个完全的逆元呢?即一个多项式 \(f\) ,是否存在 \(g\) 使得 \((f\times g)(x)=1\) ?
对于次数大于 0 的多项式 \(f\) ,不存在有限长度的符合要求的 \(g\) ,因为 \(f\) 的最高次和 \(g\) 的最高次总是无法消掉的。
那么就讨论在有限的位中的逆元,因为一般我们要求的都是序列的前一些项,之后的是不需要考虑的。
问题变成了已知一个 \(g\) ,求 \(f\) 使得
即在 \(\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\) 来逼近它,可得
这里有一个简单的结论:\(f\) 与 \(f_0\) 的前 \(\frac{n}{2}\) 位是相同的。这是因为
又 \(g\ne 0\) ,得到结论。
也就是说,\((f-f_0)^2\) 的最低非 0 位至少在 \(x^n\) ,而我们要计算的是 \(\text{mod}~x^n\) 意义下的 \(f\) ,所以后面的项在当前是没有用的。
即
由于我们要求的 \(f\) 在 \(\text{mod}~x^n\) 的意义下,使得 \(H(f)=\frac{1}{f}-g=0\) ,所以有
我们已经得到了解的一般形式。
在上面的过程中 \(H\) 是一个抽象的,满足 \(H(f)\equiv 0 \mod x^n\) 的函数,它可以是任何函数。
代入我们这里的 \(H(x)=\frac{1}{x}-g\) ,并把 \(g\) 看作一个常量,那就有
它只涉及到递归求出 \(f_0\) 和长度为 \(n\) 的乘法,即复杂度为
一个需要注意的地方:可以发现 \(f\) 的式子后面有 \(gf_0^2\) 这一项,意味着可能会出现多余的项,需要去掉。
由上述算法可以看出,多项式有模 \(x^n\) 意义下的逆元,等价于常数项有逆元。
乘方
快速幂+乘法方法,\(O(n\log ^2n)\) 。
也可以用下面讲到的方法做到 \(O(n\log n)\) 。
开根
即求 \(f\) 使得
运用上面的通用方法
构造函数 \(H(x)=x^k-g\) ,展开可得
这里使用了乘法,加法和(除法)求逆,复杂度为 \(O(n\log ^2 n)\) 。
可以发现,多项式有模 \(x^n\) 意义下的根,等价于常数项有根。
可以用下面的方法做到 \(O(n\log n)\) 。
\(\exp \& \ln\)
终于到了这个时刻。
实数的开根和乘方,两种指数上的运算,可以用对数和指数的方法,变成加减法。多项式也如此。
对一个多项式 \(f\) ,定义 \(\exp f\) (即 \(e^f\) ),为泰勒展开的形式
定义 \(\ln\) 为 \(\exp\) 的逆运算,即 \(\ln (\exp f)=f\) 。
一般我们是不会需要上面的无穷形式的,而是需要得到前 \(n\) 位,所以求解仍然在 \(\text{mod}~x^n\) 意义下进行。
如何求这两个东西呢?
\(\ln\)
求
对两边进行求导
多项式的求导和积分都是 \(O(n)\) 的,其中用到的逆元是 \(O(n\log n)\) 的,所以复杂度为 \(O(n\log n)\) 。
\(\exp\)
求 \(f\) 使得
运用通用方法,设 \(H(x)=\ln x-g\) ,那么
后记
大概就是这样啦
主要就是牛顿迭代倍增的方法和神奇的 \(\ln\) 与 \(\exp\) 。
最近会做一些多项式相关的题,研究一下生成函数吧。