乘方快速冪

乘方快速冪,是爲了解決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 }
View Code

遞歸求法:函數

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 }
View Code

二分(遞歸)求法: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 }        
View Code

固然,數學函數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     }
View Code

能夠簡單檢驗運行結果。

固然,當結果很大的時候,或要求對答案進行取模處理,這隻須要在代碼中簡單處理便可。

 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     }
View Code

 題目連接:

Raising Modulo Numbers 、 Pseudoprime numbers

相關文章
相關標籤/搜索