a的b次方怎麼求函數
pow(a, b)是數學頭文件math.h裏面有的函數spa
但是它返回值是double類型,數據有精度偏差code
那就本身寫for循環咯blog
LL pow(LL a, LL b){//a的b次方 LL ret = 1; for(LL i = 1; i <= b; i ++){ ret *= a; } return ret; }
完美遞歸
但是題目是b的範圍是1 <= b <= 1e9(#°Д°)數學
超時,妥妥的。。。for循環
看個例子class
好比計算循環
2*2*2*2*2*2*2*2*2*2*2數據
能夠這樣算
原式=4*4*4*4*4*2
=8*8*4*2
=16*4*2
你看,相同的能夠先合併,減小計算步驟
若是題目說數據很大,還須要求餘,那麼代碼就能夠這麼寫
1 LL pow_mod(LL a, LL b){//a的b次方 2 if(b == 0) return 1; 3 LL ret = pow_mod(a, b/2); 4 ret = ret * ret % MOD; 5 if(b % 2 == 1) ret = ret * a % MOD; 6 return ret; 7 }
這是遞歸寫法
而後還有遞推寫法
1 LL pow_mod(LL a, LL b){//a的b次方 2 LL ret = 1; 3 while(b != 0){ 4 if(b % 2 == 1){ 5 ret = (ret * a) % MOD ; 6 } 7 a = (a * a ) % MOD ; 8 b /= 2; 9 } 10 return ret; 11 }
對於位運算熟的小盆友,還能夠寫成位運算形式,速度又快,又好理解,在加一個求餘p,代碼以下
1 LL pow_mod(LL a, LL b, LL p){//a的b次方求餘p 2 LL ret = 1; 3 while(b){ 4 if(b & 1) ret = (ret * a) % p; 5 a = (a * a) % p; 6 b >>= 1; 7 } 8 return ret; 9 }
有了快速冪,因而,快速乘誕生了
1 LL mul(LL a, LL b, LL p){//快速乘,計算a*b%p 2 LL ret = 0; 3 while(b){ 4 if(b & 1) ret = (ret + a) % p; 5 a = (a + a) % p; 6 b >>= 1; 7 } 8 return ret; 9 }
(*´Д`*)快速乘應該不怎麼會用,無心義的東西,說不定哪天用的上
這些知識到底算不算數論呢???無論了(´∀`*)