一、题目描述
二、方法介绍
- 暴力 a乘上b次再对p取模
- 巧解
- 取模的优化(此处p为a1 a2的一个公因数)
a1 = k1*p + yushu1
a2 = k2*p + yushu2
(a1 * a2) = (……)* p + yushu1 * yushu2
所以可得(a1 * a2)%p = ((a1 % p) *(a2 % p)) % p = (yushu1 * yushu2) % p
- 对底数和指数进行处理(减少循环次数)
3^10 = (3^2)^5 = 9^5 = 9 * 9^4
当指数为奇数时提出一个,剩下的就能继续扩大底数
- 快速判断数的奇偶
位运算&
原理:比较两个数的二进制序列,相同二进制位都为1时该位返回1,否则返回零
所以只要将此时的指数与1进行&则可判断数的奇偶
- 数折半的优化
一般会使用 b /= 2这种方式,但位运算 >>可以节省时间
原理:将数的二进制位右移,空出的位置补0
代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
unsigned long long a = 0, b = 0, p = 0, ret = 1;
scanf("%llu %llu %llu", &a, &b, &p);
unsigned long long b1 = b, a1 = a;
while (b1) {
if (b1 & 1) {
ret = ((a1 % p) * (ret % p)) % p;
}
a1 = ((a1 % p) * (a1 % p)) % p;
b1 >>= 1;
}
ret %= p;
printf("%llu^%llu mod %llu=%llu", a, b, p, ret);
return 0;
}