Блог пользователя infrapolar

Автор infrapolar, история, 7 месяцев назад, По-английски

Let $$$x$$$ — value, $$$M$$$ — mod, $$$y$$$ — $$$x^{-1}\,(mod\,M)$$$.

$$$xy = kM+1$$$

where $$$k$$$ is integer

$$$yx - kM = 1$$$

You can see this is just Diophantine equation with coefficients $$$a=x$$$, $$$b=M$$$, $$$c=1$$$.

So we can use extended euclidean algorithm.

def gcd_ext(a, b):
    if b == 0:
        return a, 1, 0
    d, x, y = gcd_ext(b, a % b)
    x, y = y, x - (a // b) * y
    return d, x, y


x = 7
mod = int(1e9)
d, inv, k = gcd_ext(x, mod)
#   d is gcd(x, mod), if d isn't 1, then inverse is non exist
print(inv % mod, k)
  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

»
7 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by infrapolar (previous revision, new revision, compare).

»
7 месяцев назад, # |
Rev. 2   Проголосовать: нравится +35 Проголосовать: не нравится

Since the mod is prime in most problems, I found Euler's theorem easier to implement, because it's basically binary exponentiation, while for the extended GCD I remember having to either waste a few minutes calculating the recursion relation for $$$x$$$ and $$$y$$$ or memorize the relation altogether.

(Or maybe there's a way to think of the extended GCD more intuitively...?)

»
7 месяцев назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

Binary exponentiation is usually part of the code for modulo operations anyway, so using that to implement inverse takes 1 extra line of code. Also, extended gcd takes a non-zero amount of effort to deduce.