half-GCD
参考文献
を読もうー完ー
定理1
u,q,v,rを多項式とする。u=qv+r (deg(v)>deg(r)) のとき、qはu,vのうちxのdeg(u)冪から上位2(deg(u)-deg(v))+1桁で一意に定まる。
証明: 参考文献1を参照。
お気持ち:
$ u(x):=a_0+a_1x^1+\ldots+a_nx^n+\ldots+a_{n+m}x^{n+m}+\ldots+a_{n+2m}x^{n+2m}
$ v(x):=b_0+b_1x^1+\ldots+b_nx^n+\ldots+b_{n+m}x^{n+m}
とする。u-qvのn+m冪以上の項の係数を0にしたい。
筆算による除算によりqが求まる。
qは高々m次式、筆算の途中におけるu-qvの最上位の項はn+m冪以上である。
従って筆算の途中におけるu-qvの最上位の係数はvのn冪未満の係数の影響を受けない。
よって定理1が成り立つ(図を書こう!)。
この定理を用いて拡張ユークリッドの互除法を行うことで、GCD や $ v^{-1} \pmod u (但しGCD(u,v)=1) が高速に求まる。
N=deg(u)≧deg(v)とする。
u(x), v(x) に対して素朴に拡張ユークリッドの互除法を行うと一回の除算にO(N)掛かり、最悪ケースでは冪指数が1ずつしか減少しないため、全体で$ O(N^2)掛かる。一方、half-GCDでは$ O(N \log^2(N))となる。
拡張ユークリッドの互除法の各過程において
$ r_0=u,r_1=vと置いて
$ r_0=q_1r_1+r_2
$ r_1=q_2r_2+r_3
$ \vdots
$ r_{h-1}=q_hr_h
だとする。行列で書けば
$ \left( \begin{array}{c}\gcd(u,v) \\ 0 \end{array} \right) =\begin{pmatrix} 0 & 1 \\ 1 & -q_h \end{pmatrix}\dots\begin{pmatrix} 0 & 1 \\ 1 & -q_2 \end{pmatrix}\begin{pmatrix} 0 & 1 \\ 1 & -q_1 \end{pmatrix} \left( \begin{array}{c} u \\ v \end{array} \right) ・・・(*)
となる。従って右辺の行列積が高速に求まればよい。
gcd(u,v)=1ならば
$ \begin{pmatrix} a & b \\ c & d \end{pmatrix} := \begin{pmatrix} 0 & 1 \\ 1 & -q_h \end{pmatrix}\dots\begin{pmatrix} 0 & 1 \\ 1 & -q_2 \end{pmatrix}\begin{pmatrix} 0 & 1 \\ 1 & -q_1 \end{pmatrix}
としたとき、$ au+bv=1だから$ b \equiv v^{-1}\bmod uが求まる。
$ \mathrm{HGCD}(r_0,r_1)=一方の次数が$ \deg(r_0)/2-1以下になるまで(★)拡張互除法を適用した時の(*)の右辺の行列積を返す関数
とする。
f div g =( fをgで割ったときの商)とする。
以下のアルゴリズムを適用すると、次数の最大値が半減する。従って高々$ \log_2 ( \deg(u) )回適用すれば$ \gcd(u,v)および(*)の右辺の行列積が求まる。
=========================
$ R=\mathrm{HGCD}(u,v)
$ \left( \begin{array}{c} u \\ v \end{array} \right) \leftarrow R \left( \begin{array}{c} u \\ v \end{array} \right)
$ q \leftarrow u\ \mathrm{div}\ v
$ u \leftarrow u - qv
$ swap(u,v)
$ R \leftarrow \begin{pmatrix} 0 & 1 \\ 1 & -q \end{pmatrix} R
=========================
deg(u)-deg(v)<deg(v) を仮定してよい。さもなくば、既に★を満たしている。
m=ceil(deg(u)/2) とする。
以下のアルゴリズムを適用するとdeg(u)の次数が(3/4)倍になる。
一行目でHGCDが使えることは定理1とdeg(u)-deg(v)<deg(v)から従う。
=========================
$ R_1=\mathrm{HGCD}(u\ \mathrm{div}\ x^m, v\ \mathrm{div}\ x^m)
$ \left( \begin{array}{c} u \\ v \end{array} \right) \leftarrow R_1 \left( \begin{array}{c} u \\ v \end{array} \right)
$ q=u\ \mathrm{div}\ v
$ u \leftarrow u - qv
$ swap(u,v)
$ R_1 \leftarrow \begin{pmatrix} 0 & 1 \\ 1 & -q \end{pmatrix} R_1
=========================
ここで一旦★を満たしていないか確認する。★を満たしていなければ次を実行する。
すると、★が満たされる。返り値は$ R_2R_1。
=========================
$ R_2=\mathrm{HGCD}(u\ \mathrm{div}\ x^{m/2}, v\ \mathrm{div}\ x^{m/2})
$ \left( \begin{array}{c} u \\ v \end{array} \right) \leftarrow R_2 \left( \begin{array}{c} u \\ v \end{array} \right)
=========================
HGCDの計算量をT(N) (N=deg(u))とすると
T(N)=2T(N/2)+O(NlogN)
だからT(N)=N log^2(N)となる。
また、HGCDをlog_2(N)回適用する部分の計算量は
$ O(T(N)+T(N/2)+T(N/4)+\dots)=O(N \log^2(N))
である。