a的b次方怎么求
pow(a, b)是数学头文件math.h里面有的函数
可是它返回值是double类型,数据有精度误差
那就自己写for循环咯
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(#°Д°)
超时,妥妥的。。。
看个例子
比如计算
2*2*2*2*2*2*2*2*2*2*2
可以这样算
原式=4*4*4*4*4*2
=8*8*4*2
=16*4*2
你看,相同的可以先合并,减少计算步骤
如果题目说数据很大,还需要求余,那么代码就可以这么写
LL pow_mod(LL a, LL b){//a的b次方 if(b == 0) return 1; LL ret = pow_mod(a, b/2); ret = ret * ret % MOD; if(b % 2 == 1) ret = ret * a % MOD; return ret; }
这是递归写法
然后还有递推写法
LL pow_mod(LL a, LL b){//a的b次方 LL ret = 1; while(b != 0){ if(b % 2 == 1){ ret = (ret * a) % MOD ; } a = (a * a ) % MOD ; b /= 2; } return ret; }
对于位运算熟的小盆友,还可以写成位运算形式,速度又快,又好理解,在加一个求余p,代码如下
LL pow_mod(LL a, LL b, LL p){//a的b次方求余p LL ret = 1; while(b){ if(b & 1) ret = (ret * a) % p; a = (a * a) % p; b >>= 1; } return ret; }
有了快速幂,于是,快速乘诞生了
LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p LL ret = 0; while(b){ if(b & 1) ret = (ret + a) % p; a = (a + a) % p; b >>= 1; } return ret; }
(*´Д`*)快速乘应该不怎么会用,无意义的东西,说不定哪天用的上