zawatins-library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub zawa-tin/zawatins-library

拡張ユークリッドの互除法

extgcd(a, b, &x, &y) {
    if (b == 0) {
	    x = 1;
	    y = 0;
	    return;
    }

	extgcd(b, a % b, y, x);

	y -= a / b * x;
	
	return
}

これは何をしているの〜

モチベーション

$ax + by = gcd(a, b)$ となる $x$ 、 $y$ を求めたい。

コードの原理

extgcd(a, b, x, y) -> $ax + by = gcd(a, b)$

について

$a = pb + q$

とすると

$(pb + q)x + by = gcd(a, b)$

$b(px + y) + qx = gcd(a, b)$

となる。この式は新たな変数 $s$ $t$ とでもおいて $bs + qt = gcd(a, b)$

ユークリッドの互除法で良く使うように

$gcd(a, b) = gcd(b,\ q)$

(で $q$ は $a$ を $b$ で割ったあまり)

なので (証明(高校数学の美しい物語さん))

$bs + qt = gcd(b, q)$

となり extgcd(b, a%b, y, x)を再帰的に解けば良いことになる。

ab0になった時に自明的に方程式が解けるので。ここから再帰を戻す。

ここで、 $s = (px + y) = (\lfloor\frac{a}{b}\rfloor x + y)$ という式から $y$ を復元する必要がある。

extgcd(b, a%b, y, x)yに $s$ が代入されているため、

$y = s - \lfloor\frac{a}{b}\rfloor x$ という式変形があり、y -= a / b * xという処理が必要になっている。

コラム

$c = ax + by$ をみたす整数 $c$ は必ず $gcd(a, b)$ の倍数である。

より詳しく(けんちょんさんのQiita記事)


ラメの定理

ユークリッドの互除法の計算回数の評価にまつわる定理

割って余りを取るという操作を、最悪でも小さいほうの数の十進法での桁数の約 5 倍繰り返せば、最大公約数に達する

毎回桁数の5倍程度に成るわけではなく、大抵はもっと早く終わる模様。

なかけんの数学ノートさんの記事にわかりやすい解説記事がありました。

さらなる座学・精進

Wikipediaさん・・・ユークリッド整域(環論)

Wikipediaさん・・・連分数展開

kirika_compのブログさん・・・整数論テクニック集

はまやんはまやんはまやんさん・・・競技プログラミングにおける数学的問題まとめ