题目地址:
https://www.acwing.com/problem/content/877/
给定 n n n组 a i , b i , p i a_i,b_i,p_i ai,bi,pi,对于每组数据求 a i b i m o d p i a_i^{b_i} \mod p_i aibimodpi的值。
输入格式:
第一行包含整数
n
n
n。接下来
n
n
n行,每行包含三个整数
a
i
,
b
i
,
p
i
ai,bi,pi
ai,bi,pi。
输出格式:
对于每组数据,输出一个结果,表示
a
i
b
i
m
o
d
p
i
a_i^{b_i} \mod p_i
aibimodpi的值。每个结果占一行。
数据范围:
1
≤
n
≤
100000
1\le n\le 100000
1≤n≤100000
1
≤
a
i
,
b
i
,
p
i
≤
2
×
1
0
9
1\le a_i,b_i,p_i\le 2\times 10^9
1≤ai,bi,pi≤2×109
思路是快速幂。它的本质是将 b b b看成是二进制,然后通过计算 a 2 x , x ≥ 0 a^{2^x},x\ge 0 a2x,x≥0,来快速计算 a b a^b ab。算出 b b b的各个二进制位是容易的,而递推 a 2 x , x ≥ 0 a^{2^x},x\ge 0 a2x,x≥0也是容易的,同时 b b b的所有二进制位的个数是 log b \log b logb量级的,所以可以把复杂度降到 O ( log b ) O(\log b) O(logb)。代码如下:
#include <iostream>
using namespace std;
int n;
int a, k, p;
int fast_pow(int a, int k, int p) {
// 初始化res为乘法单位元
long res = 1 % p;
while (k) {
if (k & 1) res = res * a % p;
k >>= 1;
a = (long) a * a % p;
}
return (int) res;
}
int main() {
scanf("%d", &n);
while (n--) {
int a, k, p;
scanf("%d%d%d", &a, &k, &p);
printf("%d\n", fast_pow(a, k, p));
}
return 0;
}
每次询问时间复杂度 O ( log b i ) O(\log b_i) O(logbi),空间 O ( 1 ) O(1) O(1)。