快速幂
核心思路:反复平方法
要求
a
k
m
o
d
m
a^k\quad mod \quad m
akmodm
的结果,我们要先预计算出:
a
2
0
m
o
d
m
a
2
1
m
o
d
m
a
2
3
m
o
d
m
.
.
.
a
2
l
o
g
2
k
m
o
d
m
a^{2^0}\quad mod \quad m\\ a^{2^1}\quad mod \quad m\\ a^{2^3}\quad mod \quad m\\ ...\\ a^{2^{log_2k}}\quad mod \quad m
a20modma21modma23modm...a2log2kmodm
所以,原值
a
k
m
o
d
m
=
a
x
1
m
o
d
m
+
a
x
2
m
o
d
m
+
.
.
.
+
a
x
t
m
o
d
m
a^k\quad mod \quad m= a^{x_1}\quad mod \quad m+a^{x_2}\quad mod \quad m+...+a^{x_t}\quad mod \quad m
akmodm=ax1modm+ax2modm+...+axtmodm
比如
k
=
(
110101
)
2
k = (110101)_2
k=(110101)2
那么
k
=
2
0
+
2
2
+
2
4
+
2
5
k = 2^0 + 2^2 + 2^4 + 2^5
k=20+22+24+25
在预处理过程中,
a
2
l
o
g
2
k
m
o
d
m
=
(
a
2
l
o
g
2
k
−
1
m
o
d
m
)
∗
(
a
2
l
o
g
2
k
−
1
m
o
d
m
)
m
o
d
m
=
(
a
2
l
o
g
2
k
−
1
m
o
d
m
)
2
m
o
d
m
a^{2^{log_2k}}\quad mod \quad m = (a^{2^{log_2k - 1}}\quad mod \quad m)* (a^{2^{log_2k - 1}}\quad mod \quad m)\quad mod \quad m = (a^{2^{log_2k - 1}}\quad mod \quad m)^2\quad mod \quad m
a2log2kmodm=(a2log2k−1modm)∗(a2log2k−1modm)modm=(a2log2k−1modm)2modm
所以,我们预处理时,直接平方前一个数
给定 n 组 ai,bi,pi,对于每组数据,求出 abii mod pi 的值。
输入格式
第一行包含整数 nn。
接下来 n 行,每行包含三个整数 ai,bi,pi。
输出格式
对于每组数据,输出一个结果,表示 abiimodpi 的值。
每个结果占一行。
数据范围
1≤n≤100000
1≤ai,bi,pi≤2×109
输入样例:
2
3 2 5
4 3 9
输出样例:
4
1
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
// a^k % p
int qmi(int a, int k, int p){
int res = 1;
while(k){
if(k & 1) res = (LL)res * a % p;
k >>= 1;
a = (LL) a * a % p;
}
return res;
}
int main(){
int n;
scanf("%d", &n);
while(n --){
int a, k, p;
scanf("%d%d%d", &a, &k, &p);
printf("%d\n", qmi(a, k, p));
}
return 0;
}