求x的n次方,可以使用暴力解法,這種演算法時間複雜度為o(n),並且,當x和n比較大的時候,可能會存在溢位。
可以使用快速冪的演算法
思路
在計算機中,十進位制可以和二進位制進行轉換,利用該原理可將指數轉為
通過快速冪可將指數運算時間複雜度由o(n)降低到o(longn)。
計算xn,將n寫成2進製,在計算機中,n就是以2進製的形式儲存的,比如計算315,15的二進位制形式是1111
(0省略)23 + 22 + 21,315 = 38 * 34 * 32 * 31,這樣一來,可以利用迭代法計算315,先算出32,根據32,算出34…,就不需要遍歷15次,只需要進行4次迴圈,也就是n的二進位制左邊最後乙個為1所在的位數。利用n & 1 == 1
來判斷n的二進位制數中每一位是否為1,為1的話就相乘,每次讓n向右移一位,直到n=0。如果n為負數的話,就讓x = 1 / x,n = -n
。
**
public
static
double
pow(
double x,
int n)
//開始迴圈,條件是b不為0
while
(b >0)
return res;
}
最不好理解的就是
//開始迴圈,條件是b不為0
while
(b >0)
比如求39,9轉為二進位制為1001,39 = 38 * 31 ,也就是只要二進位制某一位上為1,就會參與運算,所以這裡才會有這個判斷if ((b & 1) == 1) res = res * x;
,每迴圈一次,讓x = x * x;
,b >>= 1;
,x正好和二進位制位數對應。
50. pow(x, n)大佬題解
現在oj**的題或者競賽的題,如果a的b次冪且b很大,那麼題中大多會讓你把結果對乙個數取餘也就是求模,例如a^b%c這種,當然如果是考高精度的題除外。
首先要知道這個公式(a*b) mod c = [(a mod c)*(b mod c)] mod c
,所以,xn % m = (x % m)n mod c,根據上面的快速冪演算法,
xn = x1*b1 * x2*b2 * x4*b2 x8*b3 … (bn是0或1,看n的二進位制對應的位置是0還是1)
xn mod m = ( x1*b1 * x2*b2 * x4*b2 x8*b3 …) mod m
根據公式可以得出,
xn mod m = ( x1*b1 * x2*b2 * x4*b2 x8*b3 …) mod m = ( x1*b1 mod m )* (x2*b2 mod m) * (x4*b2 mod m ) * (x8*b3 mod m) …) mod m
觀察每一項之間的關係
x2*b2 mod m = [ (x1*b1 mod m) * (x1*b1 mod m) ] mod m =( x1*b1 )2 mod m
x4*b2 mod m = [ ( x2*b2 mod m ) * ( x2*b2 mod m ) ] mod m = ( x2*b2 )2 mod m
x8*b3 mod m = [ (x4*b2 mod m ) * ( x4*b2 mod m ) ] mod m = ( x4*b2 )2 mod m
也就是說,後一項是前一項的平方對m取模,根據遞推關係,求出 xn mod m
**
//使用快速冪取餘,這裡n為正整數,x <<< m
public
static
intquickpowmod
(int x ,
int n,
int m)
//進行遞推,每一次迴圈,都要計算更新一次
x =(x * x )
% m;
//二進位制位移,相當於從右到左讀取位b0 b1 b2 b3 b4等等
n >>=1;
}return res;
}
另外,如果m很大的話,**裡的res、x一般都是long型別的,最後轉為int如有不足之處,歡迎指正,謝謝!
演算法提高快速冪(快速冪演算法詳解)
問題描述 給定a,b,p,求 a b mod p。輸入格式 輸入共一行。第一行有三個數,n,m,p。輸出格式 輸出共一行,表示所求。樣例輸入 2 5 3 樣例輸出 資料規模和約定 共10組資料 對100 的資料,a,b為long long範圍內的非負整數,p為int內的非負整數。所謂的快速冪,實際上...
快速冪演算法
在 上一直沒有找到有關於快速冪演算法的乙個詳細的描述和解釋,這裡,我給出快速冪演算法的完整解釋,用的是c 語言,不同語言的讀者只好換個位啦,畢竟讀 c的人較多 所謂的快速冪,實際上是快速冪取模的縮寫,簡單的說,就是快速的求乙個冪式的模 餘 在程式設計過程中,經常要去求一些大數對於某個數的餘數,為了得...
快速冪演算法
模運算 公式 a b mod n a mod n b mod n mod n a b mod n a mod n b mod n mod n a b mod n a mod n b mod n mod n 要保證n是整數 要知道a mod n和b mod n都是比n小的 利用這些共識可以有效地防止溢...