快速幂算法解决幂模问题

快速幂算法的概念

由于“指数爆炸”的现象,当a^b中指数b较大时,不能直接计算得到a ^b的结果,题目中通常会出现取余或求末几位。

模运算的基本法则

(a + b) % p = (a % p + b % p) % p 
(a - b) % p = (a % p - b % p ) % p 
(a * b) % p = (a % p * b % p) % p 

例题1

计算 x^n mod m,2 ≤ x, m ≤ 1000, 0 ≤ n ≤ 2 ^ 31 - 1

思路

由于n太大,直接暴力算会TLE,使用快速幂解决
需要运用到的公式包括

n为偶数时: x ^ n % m = ( (x^n/2 % m)* (x^n/2 % m) )%m
n为奇数时: x^n % m = ( (x% m)* (x^(n-1) % m) )%m

代码

#include<iostream>
using namespace std;

int main() {
	int x, n, m;
	cin >> x >> n >> m;
	int s = 1;
	while (n) {
		if (n & 1) s = s * x % m;//n&1即判断末位是1
		x = x * x % m;
		n >>= 1;
	}
	cout << s << endl;
	return 0;
}

注意事项

  1. n&1: 与运算 , 可以判断n是否为偶数 如果是偶数,n&1返回0;否则返回1,为奇数。(C语言中的与运算需要区别计组中位与:整数a和b按二进制对齐,按位进行与运算)
  2. n >>= 1表示将n除以2

例题2

求a^b 最后三位数表示的整数

思路

求最后三位整数即求模1000的结果

代码

#include<iostream>
using namespace std;

int main() {
	long long base, power;
	long long result = 1;
	cin >> base >> power;
	for (int i = 1; i <= power; i++) {
		result = result * base;
		result = result % 1000;
	}
	cout << result << endl;
	return 0;
}

扩展:蒙哥马利算法——RSA加密算法的核心

核心:(a * b) % p = (a % p * b % p) % p
注意:

在做ACM题时,经常都会遇到一些比较大的整数。而常用的内置整数类型常常显得太小了:其中long 和 int
范围是[-231,231),即-21474836482147483647。而unsigned范围是[0,2^32),即04294967295。也就是说,常规的32位整数只能够处理40亿以下的数。
那遇到比40亿要大的数怎么办呢?这时就要用到C++的64位扩展了。不同的编译器对64位整数的扩展有所不同。基于ACM的需要,下面仅介绍VC6.0与g++编译器的扩展。
VC6.0的64位整数分别叫做__int64与unsigned __int64,其范围分别是[-2^63,
263)与[0,264),即-92233720368547758089223372036854775807与018446744073709551615(约1800亿亿)。对64位整数的运算与32位整数基本相同,都支持四则运算与位运算等。

蒙哥马利算法代码

#include<iostream>
using namespace std;

int base, power, mod;

int Montgomery() {
	int res = 1;
	while (power) {
		if (power & 1) res = (res * base) % mod;
		power>>= 1;
		base = (base * base) % mod;
	}
	return res;
}

int main() {
	cin >> base >> power >> mod;
	cout << Montgomery() << endl;
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值