###modpowを高速で計算したい
プログラミングの問題でn^m(modP)を計算する時、1回ずつnをm回かけるとTLEになってしまいました。
(Pythonだと勝手にやってくれる関数あるらしい)
調べてみると1回のループで1回かけるのではなく複数回かけるといいらしいというのを知りました。
そりゃそうですが
参照元URLでは、二進数とbit演算で高速に処理していました。
以下が参照元URLのコードです。
ll modpow(ll a, ll n=mo-2) { ll r=1; while(n) r=r*((n%2)?a:1)%mo,a=a*a%mo,n>>=1; return r; }
いまいちやってることがわからないから出力してみた
とりあえず、それぞれの変数をcout
で各変数を出力してみました。
mはシフトしてるので2進数で出力しました。
ll modpow(ll n, ll m=mod-2) { ll r=1; while(m){ cout << "r:" << r << endl; cout << "m:" << bitset<16>(m) << endl; cout << "n:" << n << endl << endl; r=r*((m%2)?n:1)%mod,n=n*n%mod,m>>=1; } return r; }
わからないこと
m>>=1
はシフト演算で右に1シフトしてるのはわかります。(桁を1つ小さくしてる感じ)
(m%2)?n:1)
は3項演算子で今見てるbitが1
(奇数)ならn
を0
なら1
をr
にかけるということだと思います。
n=n*n%mod
もn
にn
をかけてmodをとってる。
それぞれの式の意味はわかりますが、全体で何をやってるのかわからない。
分かる方教えていただけるとありがたいです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/13 14:38
2020/05/15 08:33
2020/05/15 09:22