快速幂及取模

思想:二分,时间复杂度O(log n)

例 : 普通计算2 的 10 次幂 2*2*2*2....*2是O(n)时间复杂度

快速幂 通过平方求幂,

2的平方得   2的2次幂 

2的2次幂  再平方    得2的四次幂

2的四次幂  再 乘2 得 2的五次幂

然后2的五次幂再平方得2的10次幂

得递归表达式:

当n为偶数, 计算2的n/2次幂 再相乘

n为奇数 计算2的n-1次幂 再乘2

n为0 答案为1

递归写法:

#include <iostream>
using namespace std;
//int k=7;
int ebs(int x,int n)
{
    if(n==0)
    {
        return 1;
    }
    else if(n%2==1)
    {
        return ebs(x,n-1)*x;
    }
    else
    {
        int tmp=ebs(x,n/2);  //不能写成ebs(x,n/2)*ebs(x,n/2) 否则计算两次ebs(x,n/2)
        return tmp*tmp;      //时间复杂度变为O(n)  
    }
}
int main ()
{
    int n,m;  计算n的m次幂
    cin>>n>>m;
    int res=ebs(n,m);
    cout<<res;
    return 0;
}

当需要取模时只要再原代码中略微修改,步步取模即可

#include <iostream>
using namespace std;
int k=7;  //此处结果对7取模
int ebs(int x,int n)
{
    if(n==0)
    {
        return 1;
    }
    else if(n%2==1)
    {
        return ebs(x,n-1)*x%k;
    }
    else
    {
        int tmp=ebs(x,n/2)%k;
        return tmp*tmp%k;
    }
}
int main ()
{
    int n,m;
    cin>>n>>m;
    int res=ebs(n,m);
    cout<<res;
    return 0;
}

补充:非递归写法

#include <iostream>
using namespace std;
int main ()
{
    int n,p;   //计算n的p次幂
    cin>>n>>p;
    int res=1;
    while(p)
    {
        if(p%2==1)res=res*n;
        n=n*n;
        p/=2;
    }
    cout<<res;
    return 0;
}

取模:

#include <iostream>
using namespace std;
int k=7;  //对7取模
int main ()
{
    int n,p;
    cin>>n>>p;
    int res=1;
    while(p)
    {
        if(p%2==1)res=res*n%k;
        n=n*n%k;
        p/=2;
    }
    cout<<res;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值