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