【总结】多项式相关的各种算法


基本概念

定义形如这样的函数为多项式:

f ( x ) = ∑ i = 0 n − 1 a i x i f(x)=\sum _{i=0} ^{n-1} a_ix^i f(x)=i=0n1aixi

其中 n n n为多项式的项数(系数为0的项也是项), n − 1 n-1 n1为多项式的最高次幂, a i a_i ai为多项式中 i i i次项的系数。


符号约定&说明

  • 一般情况下,函数自变量均用 x x x表示。
  • f ( x ) f(x) f(x)表示 f f f这个多项式
  • f ( a ) f(a) f(a)表示自变量 x = a ( a 为 给 定 的 数 ) x=a(a为给定的数) x=a(a) f f f的函数值
  • f [ n ] f[n] f[n]表示多项式 f f f x n x^n xn一项的系数
  • d e g ( f ) deg(f) deg(f)表示多项式 f f f的项数,也即最高次幂 − 1 -1 1
  • 求积分时,常数项默认为 0 0 0

求导&积分

求导:

对于某一项 x n x^n xn,求导为 n x n − 1 nx^{n-1} nxn1

h ( x ) = f ′ ( x ) h(x)=f&#x27;(x) h(x)=f(x),则 h [ n ] = ( n + 1 ) f [ n + 1 ] ( 0 ≤ n &lt; d e g ( h ) ) h[n]=(n+1)f[n+1](0\leq n&lt;deg(h)) h[n]=(n+1)f[n+1](0n<deg(h)))

inline void getderivative(int n,int *f,int *h)
{
   
    for(int i=0;i<n;++i) h[i]=mul(f[i+1],i+1);
    h[n]=0;
}

积分:

h ( x ) = ∫ f ( x ) d x h(x)=\int f(x)dx h(x)=f(x)dx,则 h [ n ] = f [ n − 1 ] n ( 0 &lt; n &lt; d e g ( h ) , h [ 0 ] = 0 ) h[n]=\frac {f[n-1]}{n}(0&lt;n&lt;deg(h),h[0]=0) h[n]=nf[n1](0<n<deg(h),h[0]=0)

inline void getintegration(int n,int *f,int *h)
{
   
    for(int i=1;i<n;++i) h[i]=mul(f[i-1],inv[i]);//inv[i] i的逆元
    h[0]=0;
}

点值表示&拉格朗日插值

拉格朗日插值讲解

多项式 f ( x ) f(x) f(x)不仅可以用每一项系数表示,由拉格朗日插值法,得到也可以用 d e g ( f ) deg(f) deg(f)个二元组 ( x i , f ( x i ) ) ( x i ≠ x j , i ≠ j ) (x_i,f(x_i))(x_i\neq x_j,i\neq j) (xi,f(xi))(xi̸=xj,i̸=j)来表示,也就是用 n n n个点来描述一个 n n n项多项式(即为点值表达式):

f ( x ) ∈ { d e g ( f ) &lt; n 且 ∀ 0 ≤ i &lt; n , f ( x i ) = y i , x i ≠ x j , i ≠ j } f(x)\in \{ deg(f)&lt;n 且 \forall 0\leq i&lt; n,f(x_i)=y_i,x_i\neq x_j,i\neq j\} f(x){ deg(f)<n0i<n,f(xi)=yi,xi̸=xj,i̸=j}

这种用点描述多项式的形式称为多项式的点值表示,由点值转化为系数式的过程称为插值。


卷积(Karatsuba算法&FTT&NTT)

多项式之间的乘积称为卷积。

h ( x ) = f ( x ) ∗ g ( x ) ( ∗ 即 为 卷 积 符 号 ) h(x)=f(x)*g(x)(*即为卷积符号) h(x)=f(x)g(x)(),则 h [ n ] = ∑ i = 0 n f [ i ] g [ n − i ] ( 0 ≤ n &lt; d e g ( h ) ) h[n]=\sum _{i=0}^{n} f[i]g[n-i](0\leq n&lt;deg(h)) h[n]=i=0nf[i]g[ni](0n<deg(h))

d e g ( h ) = N deg(h)=N deg(h)=N。直接求多项式卷积,复杂度是 N 2 N^2 N2的,使用分治的 K a r a t s u b a Karatsuba Karatsuba算法可复杂度为 O ( n l o g 2 3 ) = O ( n 1.585 ) O(n^{log_2 3})=O(n^{1.585}) O(nlog23)=O(n1.585),使用 F F T / N T T FFT/NTT FFT/NTT可以将复杂度降到 N l o g N NlogN NlogN

K a r a t s u b a Karatsuba Karatsuba算法原理是利用

     ( A x 2 n + B ) ( C x 2 n + D ) = A C x n + ( ( A + B ) ( C + D ) − A C − B D ) x 2 n + B D \ \ \ \ (Ax^{\frac 2n}+B)(Cx^{\frac 2n}+D)\\=ACx^n+((A+B)(C+D)-AC-BD)x^{\frac 2n}+BD     (Axn2+B)(Cxn2+D)=ACxn+((A+B)(C+D)ACBD)xn2+BD

不断递归减少乘法次数。

F F T / N T T FFT/ NTT FFT/NTT的基本思想都是利用单位复根/单位原根并采用分治策略先将 f ( x ) , g ( x ) f(x),g(x) f(x),g(x)转化为点值表示,在点值上处理为 h ( x ) h(x) h(x)的点值表示(显然 f ( a ) g ( a ) = h ( a ) f(a)g(a)=h(a) f(a)g(a)=h(a)),再转化为 h ( x ) h(x) h(x),因为 F F T FFT FFT中涉及大量虚数实数运算,精度和常数都很感人,所以常用单模数 N T T NTT NTT,但限制模数为质数。

这里假设大家都已经会 F F T , N T T FFT,NTT FFT,NTT,就不详细展开了。

这里先给出 N T T NTT NTT代码(下文省略),以及习惯性模运算优化:

inline void NTT(int *e,int ptr,int len)//ptr=1 正变换 ptr=0 逆变换
{
   
    int i,j,k,ori,G,pd,ix,iy;G= ptr? g:inv[g];//g:原根 inv[g]:g的逆元 
    for(i=1;i<len;++i) if(i<rv[i]) swap(e[i],e[rv[i]]);
    for(i=1;i<len;i<<=1){
   
        ori=fp(G,(mod-1)/(i<<1));
        for(j=0;j<len;j+=(i<<1)){
   
            pd=1;
            for(k=0;k<i;++k,pd=mul(pd,ori)){
   
                ix=e[j+k];iy=mul(e[i+j+k],pd);
                e[j+k]=ad(ix,iy);e[i+j+k]=dc(ix,iy);
            }
        }
    }
    if(ptr) return;
    for(i=0;i<len;++i) e[i]=mul(e[i],inv[len]);
}
inline int ad(int x,int y) {
   x+=y;if(x>=mod) x-=mod;return x;}
inline int dc(int x,int y) {
   x-=y;if(x<0) x+=mod;return x;}
inline int mul(int x,int y) {
   return 1ll*x*y%mod;}

牛顿迭代

解近似方程根 h ( x ) = 0 h(x)=0 h(x)=0的一种方法。

h ( x ) h(x) h(x)当前近似解为 x n x_n xn,进一步迭代:

x n + 1 = x n − h ( x n ) h ′ ( x n ) x n x_{n+1}=x_n-\dfrac {h(x_n)}{\frac {h&#x27;(x_n)}{x_n}} xn+1=xnxnh(xn)h(xn)

引申:当 h ( x ) h(x) h(x)中嵌套一个 f ( x ) f(x) f(x)构成复合函数 h ( f ( x ) ) = 0 h(f(x))=0 h(f(x))=0,同样可以牛顿迭代倍增求解近似的 f ( x ) f(x) f(x),满足 g ( x ) ≡ h ( f n ( x ) ) ≡ 0 ( m o d   x 2 n ) g(x)\equiv h(f_n(x))\equiv 0(mod \ x^{2^n}) g(x)h(fn(x))0(mod x2n)

f n + 1 ( x ) ≡ f n ( x ) − g ( x ) g ′ ( x ) ( m o d   x 2 n + 1 ) f_{n+1}(x)\equiv f_n(x)-\dfrac {g(x)}{ {g&#x27;(x)}{}}(mod\ x^{2^{n+1}}) fn+1(x)fn(x)g(x)g(x)(mod x2n+1)

注: g ′ ( x ) g&#x27;(x) g(x) g g g h h h的偏导, g ′ ( x ) = h ′ ( f n ( x ) ) g&#x27;(x)=h&#x27;(f_n(x)) g(x)=h(fn(x))

上式可以用泰勒展开证明当 f n ( x ) f_n(x) f

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值