"""
逆元定义:
如果存在下列线性同余方程ax ≡ 1(mod n), 则x就是a在模n意义下的逆元
1.扩展欧几里得算法: 该算法可以用于求解a * x + b * y = gcd(a,b)的解,
如果a与b互质, 那么x就是a在模b意义下的逆元, 也就是ax ≡ 1(mod b)。此方
法求逆元不要求b是质数, 只要a与b互质即可, 也就是gcd(a, b) = 1。时间复
杂度为O(log a)。
2.费马小定理求逆元: 任意素数n, gcd(a, n)=1, 有a**(n-1) ≡ 1(mod n)
上述定理给出一个素数模意义下求逆元的好方法:
只要n是素数, 求a在模n意义下的逆元:
a * a**(n-2) ≡ 1(mod n)
a**(n-2)就是a的逆元, 只需要再对a**(n-2) mod n即可
"""
# 先求ax + by = gcd(a, b)的一组解
# 返回gcd(a, b), x, y
def exgcd(a, b):
# 递归出口
if b == 0:
return a, 1, 0
g, x2, y2 = exgcd(b, a % b)
x1, y1 = y2, x2 - (a // b) * y2
return g, x1, y1
# 再求ax + by = m的一组解(当m=1时就是求a在模b意义下的逆元x)
def Func(a, b, m):
g, x1, y1 = exgcd(a, b)
# m必须是gcd(a, b)的倍数才有解
if m % g != 0:
return None, None, None
x0, y0 = x1 * m // g, y1 * m // g
return g, x0, y0
# 求a在模n意义下的逆元x, 即ax ≡ 1(mod n)
# 也就是求ax + by = m(b=n, m=1)的一组解
def Inv(a, n):
g, x, y = Func(a, n, 1)
if x is None:
return None
else:
return x % n
数论-扩展欧几里得求逆元&费马小定理
最新推荐文章于 2024-05-19 23:31:32 发布