快速幂&快速幂求逆元
快速幂
c++
快速幂
/*
* 快速幂
*
* 用途:
* 用于快速求解 a ^ b % p 的数值
* a ^ b % p = (a % p) ^ b % p
* 我们可以将 b 按照二进制的形式拆分开
* = {(a % p) ^ 1 if b0 == 1 else 1} % p *
* {(a % p) ^ 2 if b1 == 1 else 1} % p *
* {(a % p) ^ 4 if b2 == 1 else 1} % p *
* ***
* {(a % p) ^ (2 ^ k)) if bk == 1 else 1} % p
* k 为 b 的二进制位数,这样的话,可以看出,复杂度为 log b
*
*/
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
int qmi(LL a, LL b, LL p) {
LL res = 1;
while (b) {
if (b & 1) {
res = res * a % p;
}
a = a * a % p;
b >>= 1;
}
return res;
}
int main()
{
int n;
LL a, b, p;
scanf("%d", &n);
while (n -- ) {
scanf("%lld%lld%lld", &a, &b, &p);
printf("%lld\n", qmi(a, b, p));
}
return 0;
}
快速幂求逆元
C++
快速幂求逆元
/*
* 快速幂求逆元
*
* 逆元定义:
* 乘法逆元,是指数学领域群G中任意一个元素a,都在G中有唯一的逆元a‘,具有性质a×a'=a'×a=e,其中e为该群的单位元。
* (注意是群中的任意一个元素都存在逆元,这里证明过于复杂) -> 这个群和环的定义,需要看数学思维方式与创新了
*
* EG:
* 4关于模7的乘法逆元为多少?
* 假设是 x ,那么
* 4x = 1 (mod 7)
* 转化为 4x + 7y = 1,x 的解
*
* 费马小定理(Fermat's little theorem):
* 如果p是一个质数,而整数a不是p的倍数,则有a ^(p-1)≡ 1(mod p)。
*
* i->因此 a 的逆元是 a ^ (p - 2)
*
* 忘记的话,可以写一下模 7 的群,自己试一试
*
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
typedef long long LL;
void solve(LL a, LL p) {
if (a % p == 0) {
printf("impossible\n");
} else {
int b = p - 2;
LL res = 1;
while (b) {
if (b & 1) {
res = res * a % p;
}
b >>= 1;
a = a * a % p;
}
printf("%lld\n", res);
}
}
int main()
{
int n;
scanf("%d", &n);
LL a, p;
while (n -- ) {
scanf("%lld%lld", &a, &p);
solve(a, p);
}
return 0;
}