C++ 快速幂取模算法

快速求b^p%k的值.

 

1 模运算与乘法的性质


乘积取模可以在乘之前先取模

x * y % d = ((x % d) * (y % d)) % d;

比如:a*a%c = ((a % c) * ( a % c)) % c;

 

2 本题公式


b为偶数时:ab mod c = ((a2)b/2) mod c
b为奇数时:ab mod c = ((a2)b/2× a) mod c

 

因此快速幂实际是分治算法,每次将b分一半,直到b=0;

 
3 实现


1> 递归实现

#include <iostream>
using namespace std;

#define Lint long long

Lint Mod(Lint a, Lint b, Lint c) {                       //求a的b次方 模c 
	if(b == 0) return 1;                                //递归边界:0次幂=1 
	if(b % 2 == 1) return a * Mod(a*a % c, b/2, c) % c; //b是奇数时
	else return Mod(a*a % c, b/2, c) % c;               //b是偶数时 
}

int main() {
	Lint b, p, k;
	cin >> b >> p >> k;
	cout << b << "^" << p << " mod " << k << "=" << Mod(b, p, k) << endl;
	return 0;
}


2> 非递归(循环)实现

 

#include <iostream>
using namespace std;

#define Lint long long

Lint mod(Lint a, Lint b, Lint c) {
	Lint ans = 1;
	while(b > 0) {
		if(b & 1) ans = ans * a % c; //位运算b&1与b%2相同 
		a = a * a % c;
		b >>= 1;                     //位运算:b/=2; 
	}	
	return ans;
}
int main() {
	Lint b, p, k;
	cin >> b >> p >> k;
	cout << b << "^" << p << " mod " << k << "=";
	cout << mod(b, p, k) % k << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值