乘方快速冪,是爲了解決a^b次方普通計算方法太慢的問題。算法
計算a的b次方,普通的for循環求法以下(O(n)):ide
1 int a(int x,int n) 2 { 3 int t=1; 4 for(int i=1;i<=n;i++) 5 { 6 t=t*x; 7 } 8 return t; 9 }
遞歸求法:函數
1 int Pow(int a,int b) 2 { 3 if(b==0) 4 return 1; 5 else 6 return Pow(a,b-1)*a; 7 }
二分(遞歸)求法:ui
1 int pow(int a,int b) 2 { 3 if(b==0) 4 return 1; 5 if(b%2==0) 6 return pow(a*a,b/2); 7 return a*pow(a*a,b/2); 8 }
固然,數學函數pow(a,b)一步解決問題。可是,由於對時間的要求,有些算法每每時間效率不高,而乘方快速冪也是(O(logn))的解法。spa
首先,3的26次方,咱們能夠發現它徹底不須要一次一次的乘,由於26次方==2^1+2^3+2^4=2+8+16code
因此3^26 = 3^2 *3^8 * 3^16,而3^2=(3^1)^2,(3^4)=(3^2)^2,3^8=(3^4)^2,因此O(logn)的時間可求出3^2,blog
3^4,3^8...固然,若是指數很大的話,咱們很差一點一點分析如何差解,因此咱們拿指數的二進制入手。遞歸
如26的二進制表示爲11010,1對應的權值爲16,8,2。它們表示的含義即爲對應的乘方次冪是須要的。固然這種分發不惟一的,你也能夠分紅8,8,4,4,2。可是爲了計算方便和應對指數冪很大的狀況,根據二進制位是1來劃分是最高效的。get
對應的算法以下:數學
1 long long Quick_Pow(long long a,long long b) 2 { 3 long long ans = 1; 4 while(b)//指數不爲0 5 { 6 if(b & 1)//b爲奇數,即二進制最右邊一位爲1時,說明須要乘這個數 7 ans = ans * a ; 8 a = a*a ;//不然底數自乘積 9 b >>= 2;//右移1位 10 } 11 return ans; 12 }
能夠簡單檢驗運行結果。
固然,當結果很大的時候,或要求對答案進行取模處理,這隻須要在代碼中簡單處理便可。
1 long long Quick_Pow(long long a,long long b,long long mod) 2 { 3 long long ans = 1; 4 while(b) 5 { 6 if(b & 1) 7 ans = ans * a % mod ; 8 a = a*a % mod ; 9 b >>= 2; 10 } 11 return ans; 12 }
題目連接: