浅谈求乘法逆元
费马小定理
在模为素数p的情况下,有费马小定理
\(a^{p-1} \equiv 1(\mod p)\)
那么\(a^{p-2} \equiv a^{-1}(\mod p)\)
也就是说\(a\)的逆元为\(a^{p-2}\)
#define ll long long
ll ksm(ll a, ll b, ll mod) {
ll ans = 1;
while(b) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod; b >>= 1;
}
return ans;
}
ll work(ll a, ll p) {return ksm(a, p - 2, p);} // 求a在模p意义下的逆元
拓展欧几里得
给定模数\(p\),求\(a\)的逆元相当于求解\(ax \equiv 1(\mod m)\)
这个方程可以转化为\(ax-my=1\)
然后套用求二元一次方程的方法,用扩展欧几里得算法求得一组\(x_0\),\(y_0\)和\(\gcd\)
检查\(\gcd\)是否为\(1\)
\(\gcd\)不为\(1\)则说明逆元不存在
若为\(1\),则调整\(x_0\)到\([0,m)\)的范围中即可
PS:这种算法效率较高,常数较小,时间复杂度为\(O(\ln n)\)
void ex_gcd(ll a, ll b, ll &x, ll &y) {
if(b == 0) {
x = 1; y = 0;
return;
}
ex_gcd(b, a % b, x, y);
ll tmp = x; x = y; y = tmp - (a / b) * y;
}
ll work(ll a, ll p) {
ll x, y;
ex_gcd(a, p, x, y);
return (x % p + p) % p;
}