算法学习笔记1:快速乘/幂算法详解


快速乘/幂详解

快速乘/幂适用范围

快速乘算法适用于计算a*b、a%b、a mod b的结果,主要目的是将乘法换为加法,防止结果过大溢出;快速幂算法适用于计算a^b、a%b、a mod b的结果,降低时间复杂度。

快速乘/幂实现原理

基于按照二进制位一步一步乘来避免重复的操作,利用前面的中间结果,从而实现快速的目的。
对于乘数b,必定可以拆成二进制,有些位为0有些为1。根据乘法分配律: a ∗ b = a ∗ ( b 1 + b 2 + b 3... ) a*b = a*(b1+b2+b3...) ab=a(b1+b2+b3...),例如, a ∗ 53 = a ∗ 110101 ( 二 进 制 ) = a ∗ ( 100000 + 10000 + 100 + 1 ) a*53 = a*110101(二进制) = a*(100000+10000+100+1) a53=a110101=a(100000+10000+100+1),可以维护一个 a n s = 0 ans=0 ans=0用于保存结果,每一位让 a ∗ = 2 a*=2 a=2,再根据b对应位是否为1,如果是就加上当前的a,即可完成快速运算,假定a=5,则具体计算流程如下图所示:
5*53快速乘的运算流程
即可计算出 5 ∗ 53 = 265 5*53=265 553=265
类似的,快速幂也是一样的过程,只不过每次a更新不是 ∗ 2 *2 2,而是 a = a ∗ a a=a*a a=aa a n s + ans+ ans+变为 a n s ∗ ans* ans

C++实现

// 一、快速幂
// 1、求a^b
int pow(int a, int k) {
	int ans = 1;
	while(k) {
		// 判断奇偶只用判断最后一位,比取模快
		if(k & 1) ans *= a;
		a *= a;
		k >>= 1;
	}
	return ans;
}
// 2、求a^b%p
int pow_mod(int a, int k,int mod) { 
    int ans = 1 % mod;
    while(k) {
        if(k & 1)  ans = (long long) ans * a % mod;  //防止在对P取模前溢出
        a = (long long) a * a % mod;
        k >>= 1;
    }
    return ans;
}

// 二、快速乘
// 1、普通快速乘
long long quickMul(long long a, long long b, long long mod) {
	long long ans = 0;
	while(b) {
		if(b & 1) ans = (ans + a) % mod;
		a = (a+a) % mod;	// 计算机中加法比乘法快
		b >>= 1;
	}
	return ans;
}
// 2、高效快速乘
long long quickMul(long long a, long long b, long long mod) {
	a %= mod;
	b %= mod;
	long long ans = 0;
	while(b) {
		if(b & 1) {
			ans += a;
			if(ans >= mod) ans -= mod;
		}
		b >>= 1;
		a <<= 1;
		if(a >= mod) a -= mod;
	}
	return ans;
}
// 3、使用long double优化
long long quickMul(long long a, long long b, long long mod) {
	a %= mod;
	b %= mod;
	long long c = (long double) a * b / mod;
	long long ans = a * b - c * mod;
	if(ans < 0)
		ans += mod;
	else if(ans >= mod)
		ans -= mod;
	return ans;
}

Python、Java实现后续补上!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值