モジュロ演算(剰余環)の復習
モジュロ演算のアルゴリズムについて勉強をした。逆元や二項係数の効率的な計算などはスニペットにした。 ここには勉強したことのメモを残す。二項係数は書く時間なかった。
読んだのは下あたり。
- 「1000000007 で割ったあまり」の求め方を総特集! 〜 逆元から離散対数まで 〜 - Qiita
- 1000000007で割ったあまりを求める問題勉強メモ - Qiita
- モジュラ逆数
- よくやる二項係数 (nCk mod. p)、逆元 (a^-1 mod. p) の求め方 - けんちょんの競プロ精進記録
関係するけど下は通読できてない。
- 【ライブラリ】mod の値が大きいときの mod 演算
- ベズーの等式 - Wikipedia
- セグメント木をあきらめた人のための平方分割 - くじらにっき++
- 整数論テクニック集 - kirika_compのブログ
- 中国剰余定理 (CRT) の解説と、それを用いる問題のまとめ - Qiita
- nCr mod mの求め方 - uwicoder - アットウィキ
関連する知識
Fermatの小定理
素数のとき。
\[ a^{p-1} \equiv 1 \mod p \]Eularのtotient関数
\( \varphi(n)\) をEularのtotuient関数として以下が成り立つ。
\[ \begin{aligned} a^{\varphi(n)-1} & \equiv 1 \mod n \\ \varphi(n) &= \vert \{m | 1 \le m \le n \wedge \gcd(m, n) = 1, \}| \end{aligned} \]ユークリッド互除法(Euclidean Algorithm)
自然数の最大公約数を求める時に使う。 \( a, b\) の公約数は \( b = qa + r\) とした際の \( b, r\) の最大公約数と等しい。 また \( \max(a, b)\) は単調減少する。 そのため剰余はいずれ \( 0\) となる。 その時の除数が最大公約数となる。
拡張ユークリッド互除法は、以下の方程式で \( a, b\) から \( x, y, d\) を求めことに使える。 ここで \( d\) は最大公約数(\( gcd(a, b), a \le b\))。
\[ ax + by = d \]\( b = qa + r\) と置き換えて \( rx' + ay' = d\) とすると下が得られる。
\[ \begin{aligned} y &= x' \\ x &= y' - b/a \end{aligned} \]また最大公約数が求まる時の式は以下になる
\[ ax + qay = a \]これは \( x = 1, y = 0\) とすると成立する。 これをGoでコードにすると下になる。(ループで書いてるのでわかりにくい)
|
|
素数pを法とする剰余群の逆元
フェルマーの小定理から \( a^{-1} \equiv a^{p-2}\) となる。 拡張ユークリッド互除法でも \( ax-np=1\) を解くことで得られる。 expGcd() とほとんど変わらないが剰余を取っている。
|
|
離散対数を求めたい
効率的なアルゴリズムは見つかっていないが擬多項式時間のアルゴリズムは存在する。 Baby-step giant-step法で \( O(\sqrt n)\) で求められる。平方分割して探索するものをBaby-step giant-step法と呼ぶらしい。
Goでの具体例は下の通り。
|
|
オイラー関数とか剰余環とか調べていたら、数学を復習したくなった。