#include "stdio.h" long long int fun(long long int a,long long int b) { long long int s=1; while(b) { s=s*a; b--; } return s; } main() { long long int i,n,s,sum; scanf("%lld",&n); { sum=fun(2,n); printf("%lld\n",sum); }
}
可以看到求几次方就要乘几次此时间复杂度为o(n).所以有了精进的算法快速幂。
快速幂
比如2的11次方 可以写成 2的五次方乘2的五次方乘2
如果用位运算来解释就更容易理解
比如11的二进制1011,如果用加权的方式来表示
11 = 1* 20 + 1* 21 + 0* 22 + 1* 23
可以推出2的十一次方的加权表示方法
211= 2^(1* 20) * 2^(1* 21) * 2^(1* 23)
所以可以通过位运算遇到0阶乘,遇到1则将累乘的值乘到结果。
#include "stdio.h" long long int fun(long int a,long long int b) { int s=1; while(b) { if(b&1) s=(s*a); a=(a*a); b>>=1; } return s; } main() { long long int i,n,s,sum; while(scanf("%lld",&n)!=EOF) { s=1; for(i=1;i<n;i++) { s=1; sum=fun(2,i); s=s+sum; } printf("%d\n",s); } }
快速幂取模
熟悉快速幂后只需理解一个数学公式ab % c = (a % c)b % c
即可写出快速幂求模
#include "stdio.h" long long int fun(long int a,long long int b,long long int p) { int s=1; while(a&&b) { if(b&1) s=(s*a)%p; a=(a*a)%p; b>>=1; } return s; } main() { long long int i,n,s,t=1,sum,s1,mo; while(scanf("%lld %lld",&n,&mo)!=EOF) { s=1; { for(i=1;i<n;i++) { sum=fun(2,i,mo); s=s+sum; } printf("%d\n",s); } } }
原文:https://www.cnblogs.com/johnfllora/p/12198726.html