链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
输入a,b,p, 求ab mod pa^b\space mod \space pab mod p.
输入描述:
第一行一个整数T , 表示T组测试用例。
接下来T行,每行3个整数a, b, p.
1≤T≤1041 \le T \le 10^41≤T≤104
1≤a,b≤1018,2≤p≤2∗109,p是素数。1 \le a, b \le 10^{18}, 2 \le p \le 2*10^9, p是素数。1≤a,b≤1018,2≤p≤2∗109,p是素数。
输出描述:
输出T行,每行表示一组测试用例的答案。
输入:
1
3 4 5
输出:
1
解释:
3^4=81
81%5=1
答案:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
LL qmi(LL a, LL k, LL p){
a = a % p;
LL res = 1;
while (k){
if (k & 1) res = res * a % p;
k >>= 1;
a = a * a % p;
}
return res;
}
int main(){
scanf("%d", &n);
while (n -- ){
LL a, k, p;
scanf("%lld%lld%lld", &a, &k, &p);
printf("%lld\n", qmi(a, k, p));
}
return 0;
}
快速幂算法(Fast Power Algorithm)是一种用于快速计算 abmodm(其中 a,b,m 是整数,b 可能非常大)的高效算法。其时间复杂度为 O(logb),相较于直接计算 a 自乘 b 次的方法(时间复杂度 O(b))有显著的性能提升。
以下是快速幂算法的一个典型C语言实现:
#include <stdio.h> | |
// 快速幂算法实现,计算 (base^exponent) % mod | |
long long fastPower(long long base, long long exponent, long long mod) { | |
long long result = 1; // 初始化结果为1 | |
while (exponent > 0) { | |
// 如果当前指数为奇数,则将当前底数乘到结果上 | |
if (exponent % 2 == 1) { | |
result = (result * base) % mod; | |
} | |
// 底数自乘,并将指数除以2 | |
base = (base * base) % mod; | |
// 指数除以2 | |
exponent /= 2; | |
} | |
return result; | |
} | |
int main() { | |
long long base, exponent, mod; | |
printf("请输入基数 (base), 指数 (exponent) 和模数 (mod): "); | |
scanf("%lld %lld %lld", &base, &exponent, &mod); | |
printf("%lld^%lld %% %lld = %lld\n", base, exponent, mod, fastPower(base, exponent, mod)); | |
return 0; | |
} |
算法解析
- 初始化:将结果初始化为1(因为任何数的0次方都是1),并将当前底数设为给定的基数。
- 循环处理:当指数大于0时,循环继续。
- 如果当前指数为奇数,则将当前底数乘到结果上(注意取模,防止溢出)。
- 无论指数是奇数还是偶数,都将底数自乘(并取模),同时将指数除以2(这相当于将问题规模减半)。
- 结束:当指数减至0时,循环结束,此时的结果即为所求。
注意
- 在每一步中取模是非常关键的,它确保了整个计算过程中数值不会溢出,同时保证最终结果满足模运算的性质。
- 快速幂算法同样适用于计算 ab(不取模)的情况,但通常我们更关注其在模运算中的应用,因为它能够处理大数运算中的溢出问题。