一般的求幂方法
正常的求幂就是一直累乘如下
#include <stdio.h>
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))//n为底数,m为指数
{
int ans=1,i;
for(i=0;i<m;i++)
ans=n*ans;
printf("%d\n",ans);
}
}
这种方法实现很简单,但是有时候挺浪费时间,于是就有了快速幂。
快速幂
关于快速幂,用一个简单的例子说明比较容易理解。
关于nm举一个实际,比如2^11。
通常我们使用累乘法需要运算10次。
211 = 2* 2* 2* 2* 2* 2* 2* 2* 2* 2* 2。
而我们可以将11转化为二进制可为1011,变成加权的表达式为
11 = 1* 20 + 1* 21 + 0* 22 + 1* 23。
211 = 2^(1* 20) * 2^(1* 21) * 2^(1* 23) 。
而我们只需要计算乘到23和三次累加操作即可,明显降低了运算时间。
我们可以通过位运算直接逐位获得m为尾值,遇0将2累乘,遇1将累乘的值乘到结果,即可得到结果。
代码如下
#include <stdio.h>
int main()
{
int pow(int n,int m);
int n,m;
while(~scanf("%d %d",&n,&m))//n为底数,m为指数
{
printf("%d\n",pow(n,m));
}
}
int pow(int n,int m)
{
int base=n,ans=1;
while(m!=0)
{
if(m&1==1)
ans=base*ans;
base=base*base;
m>>=1;
}
return ans;
}
快速幂取模
快速幂取模需要用到数学里的一个公式:
ab % c = (a % c)b % c。
在快速幂的基础上,我们可以很快将改进程序写出。
#include <stdio.h>
int main()
{
int pow(int n,int m,int c);
int n,m,c;
while(~scanf("%d %d %d",&n,&m,&c))//n为底数,m为指数,c为所需要取余的数
{
printf("%d\n",pow(n,m,c));
}
}
int pow(int n,int m,int c)
{
int base=n,ans=1;
while(m!=0)
{
if(m&1==1)
ans=(base*ans)%c;
base=(base*base)%c;
m>>=1;
}
return ans;
}
如此即为快速幂取模
快速幂运用了位运算,同时改进了求幂的算法,减少了程序运行的时间,关于位运算,此博客不做过多阐述,可自行百度解答。