快速幂
计算机二进制是个很神奇的东西,这种表示方法看似简单,里面的学问和内涵水很深,记得数字系统设计课上的加法电路快速实现就用到了将数二进制表示用移位的方式快速实现
在这里又是如此,原理大同小异,看来现在虽然不玩FPGA了,但当时学的东西是有助于当前的学习的,所以学什么都别感觉白学,用得时候没到而已,很多时候别去等用的时候,自己主动去找用得时候不更好么。
内涵
10(十进制)=(1010)(二进制)
2^10=2^(1010)=2^8 * 2^2
100(十进制)=(1100100)(二进制)
2^100=2^64 * 2^32 * 2*4
上述两个示例很有内涵,表示我们不必2*2*2……*2那样的计算常数幂,我们可以根据幂的二进制表示方法,从右向左按移位计算处理,如此大大减少计算量。
专业的角度看,这种快速方法和朴素方法的时间复杂度o(n)相比,快速幂法的时间复杂度,降到了log(n),很划算吧。
模板题
hdu 2035 p的k次方 保留最后3位
1 # include <iostream> 2 # include <cstdio> 3 # define LL long long 4 using namespace std ; 5 6 LL pow_mod(LL p, LL k,int mod) //快速幂,返回(p^k)%mod 7 { 8 LL ans = 1; 9 while(k) { 10 if (k & 1) ans = ans * p % mod; 11 p = (LL)p*p % mod; 12 k >>= 1; 13 } 14 return ans; 15 } 16 17 int main () 18 { 19 LL a , b ; 20 while (cin>>a>>b) 21 { 22 if (a==0 && b== 0) 23 break ; 24 cout<<pow_mod(a,b,1000)<<endl ; 25 } 26 27 return 0 ; 28 }
hdu 1097 p的k次方 保留最后1位
1 # include <iostream> 2 # include <cstdio> 3 # define LL long long 4 using namespace std ; 5 6 LL pow_mod(LL p, LL k,int mod) //快速幂,返回(p^k)%mod 7 { 8 LL ans = 1; 9 while(k) { 10 if (k & 1) ans = ans * p % mod; 11 p = (LL)p*p % mod; 12 k >>= 1; 13 } 14 return ans; 15 } 16 17 int main () 18 { 19 LL a , b ; 20 while (cin>>a>>b) 21 { 22 cout<<pow_mod(a,b,10)<<endl ; 23 } 24 25 return 0 ; 26 }