多项式
有关多项式的知识在FFT处有详细的讲解。
下文的$A(x),B(x),F(x)$均为多项式,简记为$A,B,F$。
其系数表示为$(a_i),(b_i),(f_i)$,点值表示为$(x,A(x)),(x,B(x)),(x,F(x))$。
本文中若无特殊说明,多项式均为$n$项。
使用$deg_A$表示多项式$A$的次数,本文中若无特殊说明,$deg_A=n-1$。
多项式的运算
多项式加法
故$A+B$的系数表示为$(a_i+b_i)$。
可以在$O(n)$的时间内完成运算。
多项式乘法
利用上式的系数表示可以在$O(n^2)$的时间内完成运算。
使用上式的系数表示可以在$O(n)$的时间内完成运算。
使用FFT可以在$O(n\log n)$的时间内将系数表示与点值表示进行转换。
多项式取模
多项式只能模一个多项式,模一个数无意义。
多项式模多项式还是一个多项式。
通常,使用多项式模$x^n$表示取该多项式的前$n$位($[0,n-1]$)。
多项式求逆
若存在$B(x)$(不一定为$n$项),满足$deg_B\le deg_A$,使得:
则称$B(x)$为$A(x)$在$\bmod {x^n}$意义下的逆元,记作$A^{-1}(x)$。
在求逆过程中,假设$n$为$2$的整数幂次,若不满足可将多项式高位补$0$达到$n$项。
当$n=1$时,$A(x)\equiv c\pmod x$,$c$是一个常数,故$A^{-1}(x)=c^{-1}$。
当$n\gt1$时,有:
假设在$\bmod x^{\frac n2}$意义下$A^{-1}(x)=B’(x)$已求出,则:
将$(1)$放到$\bmod x^{\frac n2}$的意义下,仍然有:
用$(2)-(3)$可得:
两边同时平方得:
解释一下为什么平方后模的$x^\frac n2$也会平方。
因为$B(x)-B’(x)$在模意义下为$0$,说明其$[0,\frac n2-1]$项系数均为$0$,平方后,系数为$a_i=\sum_{j=0}^ia_ja_{i-j}$,显然$j,i-j$间有一个$\lt\frac n2$,因此$a_i$也为$0$,故在$\bmod x^{n}$意义下仍为$0$。
同时乘上$A(x)$,可以得到:
这样就可以得到$\bmod x^n$意义下的逆元了,使用FFT加速多项式乘法可以在$O(n\log n)$的时间内完成当前层递归。
故总时间复杂度为:
使用主定理可知:
可看出,多项式是否存在逆元取决于其常数项是否存在逆元。
1 | void polynomial_inverse(const LL* a,const int n,LL* b) { //保证n是2的整数幂 |
多项式开根
若存在多项式$B(x)$,使得:
则称$B(x)$是$A(x)$的根。
在求多项式根的一组合法解时,假设$n$为$2$的整数幂次,若不满足可将多项式高位补$0$达到$n$项。
当$n=1$时,若$A(0)$是个变量,可能需要用到二次剩余。
当$n\gt1$时,有:
假设在$\bmod x^{\frac n2}$意义下$\sqrt{A(x)}=B’(x)$已求出,则:
将$(4)$放到$\bmod x^{\frac n2}$的意义下,仍然有:
用$(5)-(6)$可得:
两边同时平方得:
提出完全平方项得:
同时开方可以得到一组合法解:
使用$(4)$代换可得:
这样就可以得到$\bmod x^n$意义下的多项式根了,使用FFT加速多项式乘法与多项式求逆可以在$O(n\log n)$的时间内完成当前层递归。
故总时间复杂度为:
使用主定理可知:
可看出,多项式的根是否存在取决于其常数项是否存在二次剩余。
1 | void polynomial_sqrt(const LL* a,const int n,LL* b) { //保证n是2的整数幂 |
多项式求导
根据一元函数$f(x)=ax^2+bx+c$的求导规则$f’(x)=2ax+b$可知:
多项式求导即将幂系数放下来并左移一位,举个栗子:
时间复杂度$O(n)$,代码中的$n$是项数。
1 | for(int i=0; i<n-1; i++)b[i]=1ll*a[i+1]*(i+1)%mod; |
多项式积分
多项式积分就是求导的逆运算,将系数重新放回上标,并右移一位,举个栗子:
时间复杂度$O(n)$,代码中的$n$是项数。
1 | for(int i=n-1; i>=1; i--)b[i]=1ll*b[i-1]*inv[i]%mod; |
牛顿迭代法
已知函数$G(x)$,要求一个多项式$F(x)\bmod x^n$,满足:
在求牛顿迭代法的一组合法解时,假设$n$为$2$的整数幂次,若不满足可将多项式高位补$0$达到$n$项。
当$n=1$时,$G(F(x))\equiv\pmod x$,需要单独计算。
当$n\gt1$时,有:
假设在$\bmod x^{\frac n2}$意义下的解$F_0(x)$已求出,则:
将$G(F(x))$在$F_0(x)$处进行泰勒展开,得到:
根据$(8)$可知,$(F(x)-F_0(x))^2$的最低非$0$项次数大于$2\frac n2$,所以有:
根据$(7)$可知:
若计算多项式嵌套的时间复杂度为$O(C(n))$,根据主定理可知总复杂度仍然为$O(C(n))$。
然而计算多项式嵌套的最优时间复杂度为$O((n\log n)^{1.5})$,因此用它直接解题是无卵用的,不妨考虑构造$G(x),F(x)$去解决一些特殊的问题。
使用牛顿迭代法计算多项式开根
多项式开根可以使用牛顿迭代法计算。
不妨构造$F^2(x)-A(x)=0$,目的要求解$F(x)\pmod {x^n}$。
此时$G(F(x))=F^2(x)-A(x),G’(F(x))=2F(x)$,代入上述方程可得:
与上面推的式子结果相同。
多项式lnp与exp
多项式的对数有什么意义?可以理解为多项式与麦克劳林级数的复合。
根据麦克劳林级数有:
因此对于多项式$F(x)$有:
多项式lnp
对于多项式$A(x)$,现在我们要计算其对数$\ln A(x)$。
我们可以对其求导再积分:
根据链式法则可知:
那么这里需要用到多项式求逆与多项式求导。
这里需要用到多项式积分。
不难得到,多项式lnp的时间复杂度为$O(n\log n)$。
多项式exp
对于多项式$A(x)$,现在我们要计算其对数$e^{A(x)}$。
其中$A(0)=0$。
现在不能再用上面求导再积分的方法了,因为指数函数求导得到本身。
这时就需要利用牛顿迭代法。
构造$F(x)=e^{A(x)}$。
变形得到:
故构造$G(F(x))=\ln F(x)-A(x)$,此时$G’(F(x))=\frac1{F(x)}$,因此:
当$n=1$的时候,$F(x)$的常数项为$e^0=1$。
时间复杂度为:
1 | void Multiply(const int* a1,const int n1,const int* a2,const int n2,int* ans) { |
多项式$k$次幂
给出一个多项式$A(x)$,要求计算$A^k(x),k\in\mathbb Q$。
若$k\in\mathbb N$,可以使用快速幂计算,时间复杂度为$O(n\log n\log k)$,注意不要每次乘法的时候都执行$idft$,否则常数巨大。
利用对数可以将指数部分提作系数的性质,可知:
需要用到多项式exp与多项式lnp,时间复杂度仍为$O(n\log n)$。
多项式开根也可以这么计算。