扩展欧几里得算法应该是最优的求逆元算法之一 ,他和费马小定理具有同样的时间复杂度 O ( l o g ( n ) ) O(log(n)) O(log(n)),但是费马小定理需要模数为质数,扩展欧几里得算法则不需要。
逆元定义
若 a a a与 p p p互素,则满足 ( a × x ) m o d p = 1 (a\times x) mod p=1 (a×x)modp=1的 x x x为 a a a的逆元。
显然,有 ( k × p + 1 ) m o d p = 1 (k\times p+1) mod p=1 (k×p+1)modp=1( k k k为任意常数),又因为 ( a × x ) m o d p = 1 (a\times x) mod p=1 (a×x)modp=1,所以有 k × p + 1 = a × x k\times p+1=a\times x k×p+1=a×x,也就是 a × x + k × p = 1 a\times x+k\times p=1 a×x+k×p=1
只要求得任意一组满足等式的 x 、 k x、k x、k,其中的 x x x就是 a a a的逆元!
这不就是扩展欧几里得算法解决的问题吗?
扩展欧几里得算法求逆元代码:
void exgcd(ll a, ll b, ll &x, ll &y, ll &d)
{
if (!b)
{
d = a;
x = 1;
y = 0;
return;
}
exgcd(b, a % b, x, y, d);
ll temp = x;
x = y;
y = temp - (a / b) * y;
}
int main()
{
ll a, b, x, y, d;
cin >> a >> b;
exgcd(a, b, x, y, d);
x = (x % b + b) % b; //防止出现负数
cout << "a关于模b的逆元为: " << x << endl;
return 0;
}