快速幂算法

快速幂

当我们需要计算2100000000的时候,不断while循环,会使用大量的时间。因此快速幂算法出来了。简单通俗点来讲,快速幂就是将底数变得越大,指数变得越小。最终我们会得到O(log n)计算幂运算的算法

话不多说,先上代码

typedef lond lond ll;
ll mod_pow(ll x,ll n,ll mod){
	ll res=1;
	while(n>0){
		if(n&1)  res=res*x%mod;
		x=x*x%mod;
		n>>=1;
	}
	return res;
}

快速幂的讲解

首先普及下模运算的基础运算

(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p ) % p (2)
(a * b) % p = (a % p * b % p) % p (3)

其中我们只要关注第“3”条法则即可:(a * b) % p = (a % p * b % p) % p ,我们仔细研究一下这个运算法则,会发现多个因子连续的乘积取模的结果等于每个因子取模后的乘积再取模的结果。也就是说,我们如果要求:
(abc)%d=(a%db%dc%d)%d;

重点:

快速幂和核心思想是底数变大,指数变小
3 10 = 3 ∗ 3 ∗ 3 ∗ 3 ∗ 3 ∗ 3 ∗ 3 ∗ 3 ∗ 3 ∗ 3 3^{10}=3*3*3*3*3*3*3*3*3*3 310=3333333333
可以这样转换:
3 10 = ( 3 ∗ 3 ) 5 = 9 4 ∗ 9 1 = 8 1 2 ∗ 9 1 = 6561 ∗ 9 = 59049 3^{10}=(3*3)^5 =9^4*9^1 =81^2*9^1=6561*9=59049 310=(33)5=9491=81291=65619=59049
按照指数的情况应该分为偶数、奇数两种
代码如下:

long long fastPower(long long base, long long power,long long mod) {
    long long result = 1;
    while (power > 0) {
        if (power % 2 == 0) {
            //如果指数为偶数
            power = power / 2;//把指数缩小为一半
            base = base * base % mod;//底数变大成原来的平方
        } else {
            //如果指数为奇数
            power = power - 1;//把指数减去1,使其变成一个偶数
            result = result * base % mod;//此时记得要把指数为奇数时分离出来的底数的一次方收集好
            power = power / 2;//此时指数为偶数,可以继续执行操作
            base = base * base % mod;
        }
    }
    return result;
}

n&1等价于n转换为二进制然后判断最低位是否为1.如果为1就是奇数,如果为0就是偶数。
压榨性能再优化
最终代码为:

typedef lond lond ll;
ll mod_pow(ll x,ll n,ll mod){
	ll res=1;
	while(n>0){
		if(n&1)  res=res*x%mod;
		x=x*x%mod;
		n>>=1;
	}
	return res;
}

也可以采用递归的思想:

typedef lond lond ll;
ll mod_pow(ll x,ll n,ll mod){
	if(n==0)  return 1;
	ll res=mod_pow(x*x%mod,n/2,mod);
	if(n&1)	res=res*x%mod;
	return res;
}

借鉴 快速幂算法——带你从零开始一步一步优化
这篇文章可以让你理解的更深!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶辰 .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值