ACM數論之旅2---快速冪,快速求a^b((ノ`Д´)ノ作人就要堅持不懈)

 

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 }

 

 

(*´Д`*)快速乘應該不怎麼會用,無心義的東西,說不定哪天用的上

 

 

 

 

 

 

 

 

這些知識到底算不算數論呢???無論了(´∀`*)

相關文章
相關標籤/搜索