乘法逆元

1
2
3
4
5
6
7
8
9
10
11
12
13
/* a * x = 1 (mod p)   x称为a关于1模p的乘法逆元,求x
*
* 方法一:扩展欧拉定理
* a * x = 1 (mod p) => a * x + p * y = 1
* 利用扩展欧几里得法求得x和y,其中x为a关于1模p乘法逆元
*
* 方法二:费马小定理
* 费马小定理:假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡ 1(mod p) (p是质数)
* a ^ (p - 1) = 1 (mod p)
* => a * a ^ (p - 2) = 1 (mod p)
* 令x = a^-1, x = a ^ (p - 2)(mod p)
* 利用快速幂求得x
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;

typedef long long ll;
const ll MOD = 1000000007;

//扩展欧几里得
ll exgcd(ll a, ll b, ll &x, ll &y){
if(b == 0){
x = 1;
y = 0;
return a;
}
ll gcd = exgcd(b, a % b, y, x);
y -= a / b * x;
return gcd;
}

ll inv(ll a, ll b){
ll d, x, y;
d = exgcd(a, b, x, y);
return d == 1 ? (x + b) % b : -1; //1.负数情况转为正, 2.必须满足互质,否则无逆元
}

ll powMod(ll a, ll b){
ll res = 1;
while(b){
if(b & 1)
res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}

int main(){
ll a;
cin >> a;
ll result = powMod(a, MOD - 2);
cout << result << endl;
result = inv(a, MOD);
cout << result << endl;
return 0;
}
文章目录
|