快速冪詳解


快速冪的用途

顧名思義,快速冪就是很快速的冪運算,試想當你面對一個問題:求abab的時候,你的第一反應是開long long然后用for循環一點一點求。那么你就已經會了冪運算的O(b)算法。按常理來講,這樣的算法已經夠用了,但是遇到一些卡時間的題目的時候還是會T,於是快速冪應運而生。簡單地說,快速冪就是一種復雜度為O(logb)的求冪運算的算法。

快速冪的實現原理

對於ab,快速冪的時間復雜度是O(logb)的。一個整數可以被拆分成若干個2k的和。可以把b二進制分解,成為若干個2k的和,也就是將b轉換為2進制按權相加式。

b = x020 + x121 + x222 + … + xn-12n-1

再由ab = a^b = a^(x0*20 + x1*21 + x2*22 + … + xn-1*2n-1),可以減少乘法操作的次數,先是基數21~2n,先進行了n次乘法,再由有效位(b的二進制形式中,數碼為1的位)的位數m,額外進行m-1次的計算,則總共計算了n+m-1次,即得到計算次數不超過log2c + m – 1次。從原來的乘n次變為現在的最多乘2log2n次,因此,時間復雜度由原來的O(b)減小為現在的O(log2b)。

舉個例子:

求解問題: 342

第一步,將42二進制拆分:(42)10=(101010)2=1×25+0×24+⋯+0×20

那么, 342就變成了:342=31×32+0×16+1×8+0×4+1×2+0×1 =332*38*32

快速冪的迭代寫法

int qpow(int a,int b)

{

    int ret=1;

    while(b>0)

    {

        if(b&1)

            ret*=a;

        a*=a;

        b>>=1;

        }

    }

    return ret;

}

     通常,由於int類型以及long long類型的數值范圍限制,通常遇到的OJ題目需要對運算結果取模:

快速冪取模

(a*b)%m = ((a%m)*(b%m))%m;

其實快速冪取模也是用到這個

那么根據上面的定理可以推導出另一個定理:

(ab) mod c = (a * a * a........)%c =  ((a%c)*(a%c)*(a%c)*.........)%c = (a%c)b %c;

這就是快速冪取模

代碼如下:

 int pow_mod(int a ,int b)

 {

     int ans = 1 ;

     int base = a % c;

         while(b>0)

     {

           if(b&1!=0)

             ans = (ans *base)%c;

     }

      base = (base*base)%c;

     b >>= 1;

     return ans;

 }

快速冪的遞歸代碼實現

在求解ab的時候

1)當b是奇數時,那么有 ab = a * ab

2)當b是偶數時,那么有 ab = a(b/2) * a(b/2)

這個東西可以用遞歸來實現。代碼如下:

int qpow(int a,int b)

{

    if(!b)

        return 1;

    else if(b&1)

        return a*qpow(a,b-1);

    else

    {

        int t=qpow(a,b>>1);

        return t*t;

    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM