常用多项式算法

牛顿迭代公式

多项式的牛顿迭代公式用来解决以下问题:

给出 G ( x ) G(x) G(x) 求解 f ( x ) f(x) f(x) 满足方程 G ( f ( x ) ) ≡ 0 ( m o d x n ) G(f(x)) \equiv 0 \pmod {x^n} G(f(x))0(modxn)

先给出公式:

G ( A 0 ) ≡ 0 ( m o d x m ) , G ( A ) ≡ 0 ( m o d x 2 m ) G(A_0) \equiv 0 \pmod {x^m},G(A) \equiv 0 \pmod {x^{2m}} G(A0)0(modxm),G(A)0(modx2m) ,则:

A ( x ) ≡ A 0 ( x ) − G ( A 0 ) G ′ ( A 0 ) ( m o d x 2 m ) A(x) \equiv A_0(x)-\frac{G(A_0)} {G'(A_0)} \pmod {x^{2m}} A(x)A0(x)G(A0)G(A0)(modx2m)

推导过程如下:

显然, G ( A ) − G ( A 0 ) ≡ 0 ( m o d x m ) G(A) - G(A_0) \equiv 0 \pmod {x^{m}} G(A)G(A0)0(modxm) ,而 A ( x ) − A 0 ( x ) A(x)-A_0(x) A(x)A0(x) 必为 G ( A ) − G ( A 0 ) G(A) - G(A_0) G(A)G(A0) 的因式之一,因此我们取 A ( x ) − A 0 ( x ) ≡ 0 ( m o d x m ) A(x)-A_0(x) \equiv 0 \pmod {x^m} A(x)A0(x)0(modxm) 的一解即可。

G ( A ) G(A) G(A) A 0 ( x ) A_0(x) A0(x) 处泰勒展开:

G ( A ) = G ( A 0 ) + ∑ i = 1 ∞ ( A ( x ) − A 0 ( x ) ) i G ( i ) ( x ) i ! G(A)=G(A_0)+\sum_{i=1}^{\infty}\frac{(A(x)-A_0(x))^i G^{(i)}(x)} {i!} G(A)=G(A0)+i=1i!(A(x)A0(x))iG(i)(x)

由于对 i ≥ 2 i\ge2 i2 ( A ( x ) − A 0 ( x ) ) i ≡ 0 ( m o d x 2 m ) (A(x)-A_0(x))^i\equiv 0 \pmod{x^{2m}} (A(x)A0(x))i0(modx2m)

因此就有:

G ( A ) ≡ G ( A 0 ) + ( A ( x ) − A 0 ( x ) ) G ′ ( A 0 ) ≡ 0 ( m o d x 2 m ) G(A)\equiv G(A_0)+{(A(x)-A_0(x)) G'(A_0)} \equiv 0\pmod {x^{2m}} G(A)G(A0)+(A(x)A0(x))G(A0)0(modx2m)

A ( x ) ≡ A 0 ( x ) − G ( A 0 ) G ′ ( A 0 ) ( m o d x 2 m ) A(x) \equiv A_0(x)-\frac{G(A_0)} {G'(A_0)} \pmod {x^{2m}} A(x)A0(x)G(A0)G(A0)(modx2m)

注意 G ′ ( A 0 ) G'(A_0) G(A0) G G G A 0 A_0 A0 的导数。

还有一点就是,由于 A ( x ) − A 0 ( x ) ≡ 0 ( m o d x m ) A(x)-A_0(x) \equiv 0 \pmod {x^m} A(x)A0(x)0(modxm) ,因此只要知道 1 G ′ ( A 0 )   m o d   x m \frac{1}{G'(A_0)} \bmod x^m G(A0)1modxm 即可。

多项式常用函数的求法

元的线性变换

就是给定 F ( x ) F(x) F(x) F ( p x + q ) F(px+q) F(px+q)

先给出 F ( x + q ) F(x+q) F(x+q) 的求法:


F ( x ) = ∑ i = 0 m a i x i F(x)=\sum_{i=0}^{m}a_ix^i F(x)=i=0maixi

我们有

F ( x + q ) = ∑ i = 0 m a i ( x + q ) i = ∑ i = 0 m a i ( x + q ) i = ∑ i = 0 m a i ∑ j = 0 i x j q i − j C i j = ∑ j = 0 m x j j ! ∑ i = j m a i q i − j i ! ( i − j ) ! = ∑ j = 0 m x j j ! ∑ k = 0 m − j a j + k q k ( j + k ) ! k ! = ∑ j = 0 m x j j ! ∑ − k = 0 m − j a j − k ( j − k ) ! q ( − k ) ( − k ) ! F(x+q)=\sum_{i=0}^{m}a_i(x+q)^i=\sum_{i=0}^{m}a_i(x+q)^i=\sum_{i=0}^{m}a_i\sum_{j=0}^ix^jq^{i-j}C_i^j\\=\sum_{j=0}^m\frac {x^j} {j!}\sum_{i=j}^m\frac {a_iq^{i-j}i!} {(i-j)!}=\sum_{j=0}^m\frac {x^j} {j!}\sum_{k=0}^{m-j}\frac {a_{j+k}q^{k}(j+k)!} {k!}\\=\sum_{j=0}^m\frac {x^j} {j!} \sum_{-k=0}^{m-j}a_{j-k}(j-k)!\frac {q^{(-k)}} {(-k)!} F(x+q)=i=0mai(x+q)i=i=0mai(x+q)i=i=0maij=0ixjqijCij=j=0mj!xji=jm(ij)!aiqiji!=j=0mj!xjk=0mjk!aj+kqk(j+k)!=j=0mj!xjk=0mjajk(jk)!(k)!q(k)

后面的求和号里是一个卷积的形式。

由于 F ( p x + q ) = F ( p ( x + q p ) ) F(px+q)=F(p(x+\frac{q} {p})) F(px+q)=F(p(x+pq)) ,接下来就很简单了。

多项式求逆

给定 B ( x ) B(x) B(x) 1 B ( x ) ( m o d x n ) \frac{1}{B(x)} \pmod {x^n} B(x)1(modxn)

这相当于求解方程 f ( x ) B ( x ) − 1 ≡ 0 ( m o d x n ) f(x)B(x)-1\equiv 0 \pmod{x^n} f(x)B(x)10(modxn)

根据牛顿迭代公式有:

A ( x ) ≡ A 0 ( x ) − A 0 ( x ) B ( x ) − 1 B ( x ) ( m o d x 2 m ) A(x)\equiv A_0(x)-\frac{A_0(x)B(x)-1} {B(x)} \pmod {x^{2m}} A(x)A0(x)B(x)A0(x)B(x)1(modx2m)

好像陷入了瓶颈?

事实上,由于 1 G ′ ( A 0 ) \frac{1}{G'(A_0)} G(A0)1 只取前 m m m 项即可,因此:

A ( x ) ≡ A 0 ( x ) − A 0 ( x ) B ( x ) − 1 B ( x ) ≡ A 0 ( x ) − A 0 ( x ) ( A 0 ( x ) B ( x ) − 1 ) ≡ 2 A 0 ( x ) − A 0 2 ( x ) B ( x ) ( m o d x 2 m ) A(x)\equiv A_0(x)-\frac{A_0(x)B(x)-1} {B(x)} \equiv A_0(x)-A_0(x)(A_0(x)B(x)-1) \equiv 2A_0(x) -A_0^2(x)B(x) \pmod {x^{2m}} A(x)A0(x)B(x)A0(x)B(x)1A0(x)A0(x)(A0(x)B(x)1)2A0(x)A02(x)B(x)(modx2m)

多项式除法

给定 A ( x ) , B ( x ) A(x),B(x) A(x),B(x) P ( x ) , Q ( x ) P(x),Q(x) P(x),Q(x) 满足 B ( x ) P ( x ) + Q ( x ) = A ( x ) B(x)P(x)+Q(x) =A(x) B(x)P(x)+Q(x)=A(x) deg ⁡ Q &lt; deg ⁡ B \deg Q&lt;\deg B degQ<degB

f R ( x ) f^R(x) fR(x) 为将 f ( x ) f(x) f(x) 的系数从低到高反转以后的结果。
Q ( x ) Q(x) Q(x) A ( x ) A(x) A(x) 长度反转,其余多项式按原长度反转,就会有:

B R ( x ) P R ( x ) + Q R ( x ) ≡ A ( x ) ( m o d x deg ⁡ A − deg ⁡ B + 1 ) B^R(x)P^R(x)+Q^R(x) \equiv A(x) \pmod {x^{\deg A -\deg B+1}} BR(x)PR(x)+QR(x)A(x)(modxdegAdegB+1)
Q R ( x ) ≡ 0 ( m o d x deg ⁡ A − deg ⁡ B + 1 ) Q^R(x) \equiv 0 \pmod {x^{\deg A -\deg B+1}} QR(x)0(modxdegAdegB+1)

因此多项式求逆即可。

多项式开根

相当于求解方程 f 2 ( x ) − B ( x ) ≡ 0 ( m o d x n ) f^2(x)-B(x) \equiv 0 \pmod {x^n} f2(x)B(x)0(modxn)

于是

A ( x ) ≡ A 0 ( x ) − A 0 2 ( x ) − B ( x ) 2 A 0 ( x ) ≡ A 0 ( x ) 2 + B ( x ) 2 A 0 ( x ) ( m o d x 2 m ) A(x)\equiv A_0(x)-\frac{A_0^2(x)-B(x)} {2A_0(x)} \equiv \frac{A_0(x)}{2}+\frac{B(x)} {2A_0(x)} \pmod {x^{2m}} A(x)A0(x)2A0(x)A02(x)B(x)2A0(x)+2A0(x)B(x)(modx2m)

多项式的整数次方根与二次根一样都可以用类似的方式计算。

多项式的对数运算

对数运算的求解有一个简便的方法:

( ln ⁡ f ( x ) ) ′ = f ′ ( x ) f ( x ) (\ln f(x))&#x27;=\frac{f&#x27;(x)} {f(x)} (lnf(x))=f(x)f(x)

于是我们只要多项式求逆并乘法一次再求导积分各一次即可。

当然也可以尝试使用牛顿迭代法,但效率嘛233。

多项式的指数函数

相当于求解方程 l n f ( x ) − B ( x ) ≡ 0 ( m o d x n ) ln f(x) -B(x) \equiv 0\pmod {x^n} lnf(x)B(x)0(modxn)

A ( x ) ≡ A 0 ( x ) − ln ⁡ A 0 ( x ) − B ( x ) 1 A 0 ( x ) ≡ A 0 ( x ) ( B ( x ) + 1 − ln ⁡ A 0 ( x ) ) ( m o d x 2 m ) A(x) \equiv A_0(x) -\frac{\ln A_0(x)-B(x)} {\frac{1} {A_0(x)}} \equiv A_0(x)(B(x)+1-\ln A_0(x))\pmod {x^{2m}} A(x)A0(x)A0(x)1lnA0(x)B(x)A0(x)(B(x)+1lnA0(x))(modx2m)

有了对数运算和指数运算的快速算法就可以在 O ( n log ⁡ n ) O(n \log n) O(nlogn) 时间内求多项式任意指数幂了。

当然如果是 F N T FNT FNT 的话且项数不多只需要直接对点值进行快速幂,但如果是 F F T FFT FFT 的话则会因为精度问题而不能这样求。

多点求值与快速插值

多点求值

对给定的 f ( x ) f(x) f(x) x 1 , x 2 , ⋯ x n x_1,x_2,\cdots x_n x1,x2,xn ,求 f ( x 1 ) , f ( x 2 ) , ⋯ &ThinSpace; , f ( x n ) f(x_1),f(x_2),\cdots,f(x_n) f(x1),f(x2),,f(xn)

尝试使用分治算法。

我们知道 f ( a ) = f ( x ) &VeryThinSpace; m o d &VeryThinSpace; ( x − a ) f(a)=f(x) \bmod (x-a) f(a)=f(x)mod(xa) ,于是问题转化为如何求 f ( x ) &VeryThinSpace; m o d &VeryThinSpace; ( x − x i ) f(x) \bmod (x-x_i) f(x)mod(xxi)


P ( x ) = ∏ i = 1 n 2 ( x − x i ) P(x)=\prod_{i=1}^{\frac{n}{2}}(x-x_i) P(x)=i=12n(xxi)

对于 i ≤ n 2 i \le \frac{n} {2} i2n ,我们若求出 Q ( x ) = f ( x ) &VeryThinSpace; m o d &VeryThinSpace; P ( x ) Q(x)=f(x) \bmod {P(x)} Q(x)=f(x)modP(x) ,那么问题转化为求 Q ( x ) &VeryThinSpace; m o d &VeryThinSpace; ( x − x i ) Q(x) \bmod (x-x_i) Q(x)mod(xxi) ,对另一边也一样。

往下分治即可。

T ( n ) = 2 T ( n 2 ) + O ( n log ⁡ n ) = O ( n log ⁡ 2 n ) T(n)=2T(\frac{n} {2}) +O(n \log n)=O(n \log ^2 n) T(n)=2T(2n)+O(nlogn)=O(nlog2n)

若多项式长度 m &lt; n m&lt;n m<n ,则复杂度 O ( n log ⁡ 2 m ) O(n \log^2 m) O(nlog2m)

m &gt; n m &gt; n m>n ,则复杂度为 O ( n log ⁡ n + m log ⁡ 2 m ) O(n\log n + m\log ^2 m) O(nlogn+mlog2m)

快速插值

求满足 f ( x 1 ) = y 1 , f ( x 2 ) = y 2 , ⋯ f ( x n ) = y n f(x_1)=y_1,f(x_2)=y_2,\cdots f(x_n)=y_n f(x1)=y1,f(x2)=y2,f(xn)=yn 的多项式 f ( x ) f(x) f(x)

使用拉格朗日公式:

M ( x ) = ∏ i = 1 n ( x − x i ) , P i ( x ) = M ( x ) x − x i M(x)=\prod_{i=1}^n (x-x_i),P_i(x)=\frac{M(x)} {x-x_i} M(x)=i=1n(xxi),Pi(x)=xxiM(x)

f ( x ) = M ( x ) ∑ i = 1 n y i P i ( x i ) ( x − x i ) f(x)=M(x)\sum_{i=1}^n\frac{y_i}{P_i(x_i)(x-x_i)} f(x)=M(x)i=1nPi(xi)(xxi)yi

瓶颈在于 P i ( x i ) P_i(x_i) Pi(xi) ,求出 P i ( x i ) P_i(x_i) Pi(xi) 后我们只需要使用分治 F F T FFT FFT 求出 f ( x ) f(x) f(x) 即可。

显然我们不能把 P i ( x ) P_i(x) Pi(x) 单独考虑,因此尝试将其合并。

事实上

M ′ ( x ) = ∑ i = 1 n P i ( x ) , M ′ ( x i ) = P i ( x i ) M&#x27;(x)=\sum_{i=1}^n P_i(x),M&#x27;(x_i)=P_i(x_i) M(x)=i=1nPi(x),M(xi)=Pi(xi)

多点求值即可。

依然是 O ( n log ⁡ 2 n ) O(n \log^2 n) O(nlog2n)

多项式的上升/下降阶乘幂的求法

由于上升幂与下降幂的求法是一样的,这里以上升幂为例进行说明。

对于已知的 F ( x ) F(x) F(x) ,设 F ( x ) = ∑ i = 0 n a i ( x ) ( i ) F(x)=\sum\limits_{i=0}^{n}a_i(x)^{(i)} F(x)=i=0nai(x)(i)

由于对于任意 i &lt; j i&lt;j i<j ( x ) ( i ) (x)^{(i)} (x)(i) ( x ) ( j ) (x)^{(j)} (x)(j) 的因式,因此若求出 F ( x ) F(x) F(x) x ( i ) x^{(i)} x(i) 的商,我们就会有:

∑ j ≥ i a j ( x ) ( j ) = ( x ) ( i ) ⌊ F ( x ) ( x ) ( i ) ⌋ \sum_{j \ge i}a_j (x)^{(j)}=(x)^{(i)}\left \lfloor \frac{F(x)} {(x)^{(i)}} \right \rfloor jiaj(x)(j)=(x)(i)(x)(i)F(x)
这样就可以分治了。

求出 ⌊ F ( x ) ( x ) ( ⌊ n 2 ⌋ ) ⌋ \left \lfloor \frac{F(x)} {(x)^{(\left \lfloor \frac{n} {2} \right \rfloor)}} \right \rfloor (x)(2n)F(x) 之后向两边分治即可,复杂度 O ( n log ⁡ 2 n ) O(n\log ^2 n) O(nlog2n)

实际上这个问题是多点求值的一个拓展。

多项式的生成函数

会求上升幂以后实际上也自然而然的会求多项式的生成函数了。

根据生成函数的结论 1 ( x − 1 ) n = ∑ i = 0 ∞ C i + n − 1 n − 1 x i \frac{1} {(x-1)^n}=\sum\limits_{i=0}^{\infty} C_{i+n-1}^{n-1}x^i (x1)n1=i=0Ci+n1n1xi 我们就可以很容易的还原多项式的生成函数。

但实际上这么做并不够优秀233。

根据生成函数的理论,我们不妨设:

G ( x ) ( 1 − x ) n + 1 = ∑ i = 0 ∞ F ( i ) x i \frac{G(x)} {(1-x)^{n+1}}=\sum\limits_{i=0}^{\infty}F(i)x^i (1x)n+1G(x)=i=0F(i)xi

那么

G ( x ) = ( 1 − x ) n + 1 ∑ i = 0 ∞ F ( i ) x i G(x)=(1-x)^{n+1}\sum\limits_{i=0}^{\infty}F(i)x^i G(x)=(1x)n+1i=0F(i)xi

实际上只需要多点求值之后做一次卷积即可,除去多点求值复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

点值、生成函数与上升/下降阶乘幂的相互转化

点值和生成函数可以 O ( n log ⁡ n ) O(n\log n) O(nlogn) 时间内相互转化,那上升/下降阶乘幂呢?。

我们实际上可以用生成函数法 O ( n log ⁡ n ) O(n\log n) O(nlogn) 求出多项式的上升阶乘幂形式。

得到生成函数分子 G ( x ) G(x) G(x) 后直接令 H ( 1 − x ) = G ( x ) H(1-x)=G(x) H(1x)=G(x) 也即 H ( x ) = G ( 1 − x ) H(x)=G(1-x) H(x)=G(1x) 将生成函数函数还原为 ∑ i = 1 n + 1 a i ( 1 − x ) i \sum\limits_{i=1}^{n+1}\frac{a_i} {(1-x)^i} i=1n+1(1x)iai 的形式即可求出上升幂。

不过注意这时得到的上升幂并不是真正意义上的上升幂,而是 ∑ i = 0 n a i ∏ j = 1 i ( x + j ) \sum\limits_{i=0}^{n} a_i\prod\limits_{j=1}^{i}(x+j) i=0naij=1i(x+j)

要改成真正意义上的上升幂需要从后往前扫一遍修正系数。

下降阶乘幂和生成函数之间的转化也是类似的。

将生成函数改写为 ∑ i = 1 n + 1 a i − 1 x i − 1 ( 1 − x ) i = ∑ i = 0 n a i x i ( 1 − x ) n − i ( 1 − x ) n + 1 \sum\limits_{i=1}^{n+1} \frac{a_{i-1}x^{i-1}} {(1-x)^i}=\frac{\sum_{i=0}^{n}a_ix^{i}(1-x)^{n-i}} {(1-x)^{n+1}} i=1n+1(1x)iai1xi1=(1x)n+1i=0naixi(1x)ni 即可。

二项式反演即可(太懒推不动式子了,剩下的自己推吧)。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值