快速幂详解

一、引入

当我们遇到一个很简单的问题,例如计算 a b m o d    n a^b \mod n abmodn 的结果,我们可以使用多个循环迅速解决,时间复杂度约为 O ( b ) O(b) O(b)

代码就像这样:

	sum=1;
    for(int i=1;i<=b;++i){
    	sum=sum*a%m;
    }
    cout<<sum;

当然,如果是一些简单的题目,自然没有任何的问题,但是当我们遇到需要快速求解的题目或需要求解多个时,显然会超时,因此,我们需要考虑如何优化这一个算法

二、快速幂

对于一个线性求解的问题,我们往往可以使用分治的思想,例如:

对于 a b a^b ab,当 b b b 是偶数时, a b a^b ab 就可以拆分成 a b ÷ 2 + a b ÷ 2 a^{b\div 2}+a^{b\div 2} ab÷2+ab÷2 同理,当 b b b 为奇数时, a b a^b ab 就可以拆分成 a b ÷ 2 + a b ÷ 2 × a a^{b \div 2}+a^{b\div 2}\times a ab÷2+ab÷2×a ,然后通过一次乘法运算,就可以获得 a b a^b ab 的结果。我们只需要继续递归上述计算方法, b b b 最终一定会分解到 1 ,这种计算方法就叫做快速幂算法。

代码实现上述算法:

int pow(int a,int b,int n){  // a,b,n 与 a^b mod n 对应
	if(b==1) return a; //当 b 已经分解到 1 的时候,返回 a,否则继续分解
	if(b%2==0){   //判断 b 是偶数还是奇数
		int t=pow(a,b/2,n);  //如同上面所描述的方法,把 a^b 分解为 a^(b÷2)×a^(b÷2)
		return t*t%n;  //返回计算结果,也就是 a^(b÷2)×a^(b÷2)%n
	} else {
		int t=pow(a,b/2,n);  //如同上面所描述的方法,把 a^b 分解为 a^(b÷2)×a^(b÷2)×a
		return t*t*a%n;   //返回计算结果,也就是 a^(b÷2)×a^(b÷2)×a%n
	}
}

非递归的代码如下(原理一样,就不做过多解释了):

int pow(int a, int b) {
                int ans=1,base=a;
                while(b!=0) {
                    if(b&1)//判断b的奇偶
                       ans*=base;//当n为奇数时,乘以base(当前权值下的a)
                    base*=base;
                    b>>=1;//等价于b/=2
               }
               return ans;
           }

还有有疑问可以在此处寻找更多优秀文章或者在评论中提出哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值