(復學梳理) 快速冪求模[程式碼思想詳解]
阿新 • • 發佈:2019-02-15
首先,給出程式碼:
const LL mod = 1000000007;
LL quick(LL a,LL b)
{
LL ans=1;
a=a%mod;
while(b!=0)
{
if(b&1) ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
程式碼看起來十分的簡潔。快速冪求模,就是解決大數求高次方後取模的演算法。
最基礎的求高次方的演算法,就是使用for迴圈來實現,但是這個演算法的時間複雜度就和次方數成正比了,當次方數很大時,如10^15時,那麼演算法一定是超時的。
那麼如何快速求出呢?這就運用了二進位制的特點了。
例如: 當我們要求2^7時,for迴圈要使用6次乘法,次數和次方數成正比。
但是,我們知道,7的二進位制是111,所以我們可以將2^7分解為:2^1 * 2^2 * 2^4,只用使用2次乘法,和二進位制的位數成正比。
也就是,將7按照二進位制分解為:7=1+2+4
整體思想就是,利用二進位制的特點,將值的數量級計算,轉化為位數的數量級計算。
程式碼詳解:
求a^b:
將b看成二進位制的0,1陣列,從低位向高位移動掃描。
當第i位為1時,表示要乘上一個a^(2^i),而每向高位移動一位,a^(2^i)的結果就會翻一倍。
所以程式碼中,用ans來表示最後的答案,而用a來表示:若第i位1時,a^(2^i)的值。
而b用來控制。