快速幂的c++实现

何为快速幂

我们以洛谷P1226【快速幂】为例
最简单的做法就是直接暴力

#include<bits/stdc++.h>
using namespace std;

int main(){
	long long a,b,p;
	cin>>a>>b>>p;
	long long ans=1;
	for(int i=0;i<b;i++){
		ans*=a;
	}
	cout<<ans;
}

但我们不难发现,会TLE
所以快速幂就应用而生

算法思想

对数学敏感的盆友就会想到:
a b = ( a 2 ) b 2 a^{b}=\left(a^{2}\right)^{\frac{b}{2}} ab=(a2)2b
b {b} b变成 b 2 \frac{b}{2} 2b了,数据规模减小了耶
所以我们可以用循环直接重复此过程

#define ll long long

ll fastPower(ll a,ll b,ll p){
	while(b>0){
		a*=a; //乘幂
		a%=p; // 取余,防止爆ll
		b/=2; // 减少数据规模
	}
	return a;
}

但我们很快又发现了问题
b {b} b变成 b 2 \frac{b}{2} 2b时,数学中没啥毛病
but,在c++中,会直接向下取整,这样就会丢精度

所以,当为奇数时,还要做一些事情,不让他丢精度

我们不妨用一个ans变量存储一下结果
再加上之前的代码

#define ll long long

ll fastPower(ll a,ll b,ll p){
	ll ans=1;
	while(b>0){
		if(b%2){  // 若为奇数
			ans*=x; // 存储精度丢失部分
			ans%=p;
		}
		a*=a; //乘幂
		a%=p; // 取余,防止爆ll
		b/=2; // 减少数据规模
	}
	return ans;
}

a,b,ans的变化如下表所示

abans
2101
2 2 = 4 2^{2}=4 22=451
4 2 = 16 4^{2}=16 42=1614
1 6 2 = 256 16^{2}=256 162=25614
25 6 2 256^{2} 25620 4 ⋅ 1 6 2 = 1024 4\cdot16^{2}=1024 4162=1024

(例:计算 2 10 2^{10} 210

如果我们在think,think
就可以把他简化成究极无敌简洁的形式:

#define ll long long

ll fastPower(ll a,ll b,ll res,ll p){
	if(y==0) return res;
	else if (!y%2) return fastPower(a*a%p,y/2,res,p);
	return fasePower(a*a%p,b/2,res*x%p,p);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值