1. 程式人生 > >(復學梳理) 快速冪求模[程式碼思想詳解]

(復學梳理) 快速冪求模[程式碼思想詳解]

首先,給出程式碼:

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用來控制。