这篇博客好像咕咕咕了很久,本来是应该学完NTT之后搞的,然而那段时间在回归常规……
求导
对于一个普通多项式 A(x)=∑aixbi A ( x ) = ∑ a i x b i ,它的导数为 A′(x)=∑aibixbi−1 A ′ ( x ) = ∑ a i b i x b i − 1 。
补充一些式子 (AB)′=u′v+uv′ ( A B ) ′ = u ′ v + u v ′
时间复杂度 O(n) O ( n ) 。
积分
对于一个普通多项式 A(x)=∑aixbi A ( x ) = ∑ a i x b i ,积分和求导是一种逆操作,那么对它做积分之后的形式是 A(x)=∑aibi+1xbi+1 A ( x ) = ∑ a i b i + 1 x b i + 1 。注意到这个是没有常数项的,那么为了还原函数,我们还需要引入常数项。
时间复杂度 O(n) O ( n ) 。
反转
对于多项式 A(x)=∑aixi A ( x ) = ∑ a i x i ,其反转后的多项式记做 AR(x)=∑an−i−1xi A R ( x ) = ∑ a n − i − 1 x i ,即相当于把所有的系数翻转。也有以下这种形式
时间复杂度 O(n) O ( n ) 。
多项式对数
对于给定的多项式 A(x) A ( x ) ,求一个多项式 f(x) f ( x ) 满足 f(x)=lnA(x)(modxn) f ( x ) = ln A ( x ) ( mod x n )
时间复杂度 O(nlogn) O ( n log n ) 。
牛顿迭代
普通牛顿迭代
用于求一个函数 f(x) f ( x ) 的零点。
- 瞎猜一个零点x
- 取函数在x处的切线的零点为新的x,再继续迭代
这个步骤可以简化为一个递推
有一种泰勒展开的考虑方法,在x处进行泰勒展开
我们知道泰勒展开是展开项越多,与原函数就拟合得越好。但是为了简便,我们可以只保留线性部分,也就是前两项,同样可以得到那个递推式。但由于我们每次只保留的线性部分,所以结果是不精确的,需要多次迭代才能满足精度上的要求。
能用牛顿迭代求零点的函数的充分条件是,要二阶可导且起始点位于待求的零点的邻近区域。但是也有可能这个区域只包含了零点,比如 f(x)=x13 f ( x ) = x 1 3 。要注意有可能初始点处的导数恰好为0,此时只需要重新选点即可。
多项式牛顿迭代
用于求满足 g(f(x))≡0(modxn) g ( f ( x ) ) ≡ 0 ( mod x n ) 的多项式 f(x) f ( x ) 。
如果n=1,那么就只有常数项,直接算即可。
思想有点类似于多项式求逆,基本步骤是和上面类似的。
假设我们已经算出来了 f0(x) f 0 ( x ) 满足 g(f0(x))≡0(modx⌈n2⌉) g ( f 0 ( x ) ) ≡ 0 ( mod x ⌈ n 2 ⌉ ) 。我们把 f0(x) f 0 ( x ) 看作普通牛顿迭代法中的 x0 x 0 ,那么我们在此处进行泰勒展开
f(x) f ( x ) 与 f0(x) f 0 ( x ) 的后 ⌈n2⌉ ⌈ n 2 ⌉ 是一样的,注意到第三项的 (f(x)−f0(x))2 ( f ( x ) − f 0 ( x ) ) 2 ,则其后 n n 项必然是为0,更高次的同理。那么我们可以得到结论,多项式牛顿迭代求出的是精确解。
用其可以做多项式求逆,多项式开根,多项式求exp。
多项式求逆
对于给定的多项式 A(x) A ( x ) ,求一个多项式 f(x) f ( x ) 满足 f(x)=1A(x)(modxn) f ( x ) = 1 A ( x ) ( mod x n )
我们尝试构造这样的一个多项式 G(x) G ( x ) ,使得其零点的多项式即为 f(x) f ( x ) ,则有
求其零点,那么我们直接代入牛顿迭代的式子中即得
时间复杂度 T(n)=T(n2)+O(nlogn)=O(nlogn) T ( n ) = T ( n 2 ) + O ( n log n ) = O ( n log n ) 。
多项式开根
对于给定的多项式 A(x) A ( x ) ,求一个多项式 f(x) f ( x ) 满足 f2(x)=A(x)(modxn) f 2 ( x ) = A ( x ) ( mod x n )
我们同样可以构造一个多项式 G(f(x))=f2(x)−A G ( f ( x ) ) = f 2 ( x ) − A ,即得
时间复杂度 T(n)=T(n2)+O(nlogn)=O(nlogn) T ( n ) = T ( n 2 ) + O ( n log n ) = O ( n log n ) 。
多项式求exp
对于给定的多项式 A(x) A ( x ) ,求一个多项式 f(x) f ( x ) 满足 ef(x)=A(x) e f ( x ) = A ( x ) 。
构造 G(x)=lnf(x)−A(x) G ( x ) = ln f ( x ) − A ( x )
时间复杂度 T(n)=T(n2)+O(nlogn)=O(nlogn) T ( n ) = T ( n 2 ) + O ( n log n ) = O ( n log n ) 。
多项式除法与取模
A(x)=B(x)D(x)+R(x) A ( x ) = B ( x ) D ( x ) + R ( x ) ,其中 A(x) A ( x ) 为被除数, B(x) B ( x ) 为除数, D(x) D ( x ) 为商, R(x) R ( x ) 为余数。它们满足 deg(R)<deg(B)<deg(A) d e g ( R ) < d e g ( B ) < d e g ( A ) , deg(D)=deg(A)−deg(B)+1 d e g ( D ) = d e g ( A ) − d e g ( B ) + 1 。
我们只需要求出 D(x) D ( x ) 即可,这样 R(x) R ( x ) 可以代入得到。我们当然希望能利用到逆元,联系一下与多项式逆元的区别,我们来解决这些区别即可。
- 有余数
- 没有模
为了方便描述,我们不妨设 deg(A)=n,deg(B)=m d e g ( A ) = n , d e g ( B ) = m ,则有 deg(D)=n−m+1 d e g ( D ) = n − m + 1 。模不能影响 D(x) D ( x ) ,又要能消去 R(x) R ( x ) 的影响,那么可以考虑模 xn−m+1 x n − m + 1 。我们知道在做NTT的时候 N>n N > n ,这样即是把从N开始的至少m-1项的系数给直接删去了。注意到 deg(R)<m d e g ( R ) < m ,那么我们把R进行反转即可。
那么我们可以得到 AR(x)≡BR(x)DR(x)(modxn−m+1) A R ( x ) ≡ B R ( x ) D R ( x ) ( mod x n − m + 1 )
得到 D(x) D ( x ) 后直接利用原来的等式即可求得 R(x) R ( x ) 。
时间复杂度 O(nlogn) O ( n log n ) 。
多项式k次方
时间复杂度 O(nlogn) O ( n log n ) 。