快速幂与快速幂取模

一般的求幂方法

正常的求幂就是一直累乘如下

#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;
}

如此即为快速幂取模

快速幂运用了位运算,同时改进了求幂的算法,减少了程序运行的时间,关于位运算,此博客不做过多阐述,可自行百度解答。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值