1. 程式人生 > >關於快速冪演算法有效性的證明

關於快速冪演算法有效性的證明

在讀這篇文章之前,請確保已經完全明白二進位制基礎以及其他與本文相關的二進位制的知識


  • 首先,假設我們要求3^{101},設a=3,b=101
  • 將b轉化為二進位制表示,則為:1100101
  • 通過二進位制基礎,我們知道:b=2^{0}+2^{2}+2^{5}+2^{6}=101101=2^{0}+2^{2}+2^{5}+2^{6}
  • 通過乘法原理,我們知道:3^{c}*3^{d}=3^{c+d}3^{c+d}=3^{c}*3^{d}
  • 因此,可以推出:3^{101}=3^{2^{0}}*3^{2^{2}}*3^{2^{5}}*3^{2^{6}}=3^{1}*3^{4}*3^{32}*3^{64}=3^{101}
  • 那麼,我們想象一下:如果計算2^{x}(設x為任意數)的時間複雜度為O(1),則計算3^{101}的時間複雜度就成為了O(6),也就是O({log_{2}}^{101})
  • 也就是說,計算p^{n}的時間複雜度也就成為了O({log_{2}}^{n})

那麼,接下來的問題就是:怎麼將計算2^{x}的時間複雜度降為O(1).

我們的思路是:首先,我們迴避掉直接計算2^{x}這個問題。因為在對一個數g進行右移的過程中,假設每次右移一位,則一共需要右移{log_{2}}^{g}

次(如果不熟悉這裡可以自己手寫驗證一下).那麼,在將在指數右移的過程中加上遞推即可完成快速冪的運算。

理論部分完畢,下面是具體實現。


#include<cstdio>
#include<iostream>
using namespace std;
int poww(int,int);
int main(){
    cout<<poww(2,101)<<endl;
}
int poww(int a,int b){
    int ans=1;
    while(b!=0){
        if(b&1){//如果目前b的最後一位為1
            ans*=a;//向結果賦值(遞推的部分)(這裡a直接加入了ans的運算)
        }
        a*=a;//(a間接加入ans的運算)這裡會在文章下面解釋
        b=b>>1;//指數右移一位
    }
    return ans;
}
//該程式碼僅作參考,由於2^101超過了int的範圍,實際上無法輸出最終結果(但在不超範圍的情況下可以正常使用)

 因為乘法的時間複雜度是O(1),所以快速冪的時間複雜度O(logN)成立