问题描述
求 a 的 b 次方对 p 取模的值。
输入格式
三个整数 a,b,p ,在同一行用空格隔开。
输出格式
输出一个整数,表示a^b mod p的值。
数据范围
0≤a,b≤109
1≤p≤109
输入样例:
3 2 7
输出样例:
2
由于是二进制,很自然地想到用位运算这个强大的工具:&和>>
&运算通常用于二进制取位操作,例如一个数 & 1 的结果
就是取二进制的最末位。还可以判断奇偶x&10为偶,
x&11为奇。 >>运算比较单纯,二进制去掉最后一位
在实际问题中,题目常常会要求对一个大素数取模,这是因为计算结果可能会非常巨大,但是在这里考察高精度又没有必要。这时我们的快速幂也应当进行取模,此时应当注意,原则是步步取模,如果MOD较大,还应当开long long。
部分截图
代码&注释
#include <iostream>
using namespace std;
int main() {
long long a, b, p, res = 1; // a^b % p = ?
scanf("%ld%ld%ld", &a, &b, &p);
while(b) {
// b & 1 用 & 运算符得到 b 二进制的最后一位
// 最后一位可能是 0 或者 1
// 如果是 1,答案 res 需要乘以 a 取模 并把结果保存到 res 中
// 这里用到了 整数转为二进制形式的知识
// 以b==11为例,b用二进制表示为1011,二进制从右向左算,
// 但乘出来的顺序是 a^(1 * 2^0)*a^(1 * 2^1)*a^(0 * 2^2)*a^(1 * 2^3),
// 是从左向右的。我们不断的让a *= a目的即是累乘,因为当 b 右移了一位后
// 2^x 中的 x 也要增加,而且正好是 a 的平分,即,a = a * a
// 如果等于 b & 1 == 1 成立,则 b 作为 a 的 次幂,贡献了结果,就要存在res中
// 所以有 res = res * a
// 所有的 % (取模)操作都不会影响最终的取模结果,而且
// 取模可以防止数据溢出
if(b & 1) res = res * a % p;
b >>= 1; // b 右移了一位后,a 也需要更新
a = a * a % p;
}
printf("%ld\n", res % p);
return 0;
}
网络资源很丰富
你想要的答案要自己搜,自己思考,自己总结一下