费马小定理
在模为素数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;
}