淺談多項式除法 Part 1: 快速演算法

計算兩個不超過 n 次的複係數一元多項式 f(x)g(x) 的乘積,可以藉由 FFT (Fast Fourier Transform, 快速傅立葉變換) 在 O(nlogn) 時間內求得。更一般的情形,設 R 為一個環且 f(x),g(x)R[x],則 f(x)g(x) 可以用 Karatsuba 演算法O(nlog23) 時間內求得,也比 naïve 演算法的 O(n2) 快。假設多項式乘法的時間複雜度是 O(M(n)),這篇將介紹如何在 O(M(n)) 時間內計算 f(x)÷g(x) 的商式和餘式。

先定義好我們的問題:設 R 為一個有 1 的環,f(x),g(x)R[x] 滿足
  • degf=n
  • g(x)0,degg=mn
  • gxm 項係數為 1
我們要找出 q(x),r(x)R[x] 使得
  • f(x)=q(x)g(x)+r(x)
  • degr<m
不難從長除法證明 qr 存在且唯一。接著,引入反轉算子 R:R[x]R[x],定義對於所有的 h(x)R[x]
(Rh)(x)={0,if h(x)=0,xph(1x),if degh=p.
事實上,若 h(x)=α0+pi=1αixi0,則 (Rh)(x)=αp+pi=1αpixi。這樣一來,就有
(Rf)(x)={(Rq)(x)(Rg)(x),if r(x)=0,(Rq)(x)(Rg)(x)+xndegr(Rr)(x),otherwise.
注意當 r(x)0 時,有 ndegrnm+1。所以我們總是有 (Rf)(x)modxnm+1=((Rq)(x)(Rg)(x))modxnm+1
如果我們能找到 (Rg)(x)1modxnm+1,就有 (Rq)(x)modxnm+1=((Rf)(x)(Rg)(x)1)modxnm+1
又因為 degq=nm,事實上我們有 (Rq)(x)modxnm+1=(Rq)(x),因此上式可以改成 (Rq)(x)=((Rf)(x)(Rg)(x)1)modxnm+1
一旦求得了 (Rg)(x)1modxnm+1,就能在 O(M(n)) 時間內計算出 q(x) 以及 r(x)=f(x)q(x)g(x)。接下來我們把目標放在:給定 hR[x]kZ1,其中 h 的常數項為 1,求出 h1modxk

不難發現 h1modx=1。令 lZ1 並假設 s:=h1modxl 為已知,我們介紹一個在 O(M(l)) 時間內求出 h1modx2l 的演算法。

h(x)=h0+h1xl+(higher terms),其中 h0,h1R[x]degh0,degh1l1。我們想找某個 a,bR[x],其中 dega,degbl1,使得 (a+bxl)hmodx2l=(a+bxl)(h0+h1xl)modx2l=(ah0+(ah1+bh0)xl)modx2l=1
注意 (a+bxl)hmodxl=((a+bxl)hmodx2l)modxl=ah0modxl=ahmodxl=1
所以 a=s。接著,令 ah0=sh0=1+cxl,其中 cR[x],則 (1)可以改寫成 (1+(sh1+bh0+c)xl)modx2l=1
因此 sh1+bh0+c=0modxl,亦即 b=s(sh1+c)modxl,此時的 a+bxl 就是 h1modx2l。因為 s,h0,h1,c 的次數都不超過 l1,由 h1modxl 計算 h1modx2l 的時間複雜度是 O(M(l))

最後,假設計算 h1modxk 的總時間為 T(k),利用這個倍增法,可知 T(k)=T(k2)+O(M(k))=O(M(k)),也就是計算 q(x)r(x) 只需要 O(M(n)) 時間,和乘法一樣。

我是在這裡學到這個演算法的。至於實作部分,有興趣的話可以參考我放在github上的整係數多項式模板

留言

這個網誌中的熱門文章

2020 全國賽驗題心得

水母上 Divide-and-Conquer

109 學年度全國資訊學科能力競賽各題詳解