快速幂,该方法用来快速求解 a k a^k ak取余p的值,时间复杂度为O(logk)。
核心思想:k一定可以表示成 k = Σ j 2 j k=\Sigma_j2^j k=Σj2j这样的形式,例如当k=9时, 9 = 2 0 + 2 3 9=2^0+2^3 9=20+23。故,我们先预处理出 a a a、 a 2 a^2 a2、 a 4 a^4 a4等等取余p的值,然后
a 9 = ( a % p ) ⋅ ( a 8 % p ) a^9=(a \% p) \cdot (a^8 \% p ) a9=(a%p)⋅(a8%p)
将上述思路转换为代码,如下所示,
int qmi(int a, int k, int p) {
long long res = 1;
while (k) {
if (k & 1) res = (long long)res * a % p;
k >>= 1;
a = (long long)a * a % p;
}
return res;
}
求 m^k mod p,时间复杂度 O(logk)。
int qmi(int m, int k, int p)
{
int res = 1 % p, t = m;
while (k)
{
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
题目1:n组(a, k, p),请返回 a k a^k ak取余p的值。
#include
using namespace std;
int n;
int qmi(int a, int k, int p) {
long long res = 1;
while (k) {
if (k & 1) res = (long long)res * a % p;
k >>= 1;
a = (long long)a * a % p;
}
return res;
}
int main() {
cin >> n;
while (n--) {
int a, k, p;
cin >> a >> k >> p;
cout << qmi(a, k, p) << endl;
}
return 0;
}
题目2:求逆元,即求a^(p-2) % p的值。
#include
using namespace std;
int n;
int qmi(int a, int k, int p) {
long long res = 1;
while (k) {
if (k & 1) res = (long long)res * a % p;
k >>= 1;
a = (long long)a * a % p;
}
return res;
}
int main() {
cin >> n;
while (n--) {
int a, p;
cin >> a >> p;
if (a % p == 0) {
cout << "impossible" << endl;
} else {
cout << qmi(a, p-2, p) << endl;
}
}
return 0;
}