==================↵
↵
↵
$$x^{p-1}\equiv 1\pmod p$$↵
↵
↵
$$x^{p-2}\equiv x^{-1}\pmod p$$↵
↵
~~~~~↵
int binpow(int a, int n) {↵
int res = 1;↵
while (n) {↵
if (n&1) res = 1LL * res * a % mod;↵
a = 1LL * a * a % mod;↵
n >>= 1;↵
}↵
return res;↵
}↵
int inv(int x) {↵
return binpow(x, mod - 2);↵
}↵
~~~~~↵
==================↵
↵
For example, we can write the modular inverse like this
Этот способ отлично работает. Но для такой частой операции хочется иметь что-то короче.↵
==================↵
↵
Например, обратный элемент можно записать так:↵
↵
~~~~~↵
int inv(int x) {↵
return x == 1 ? 1 : mod - 1LL * (mod / x) * inv(mod % x) % mod;↵
}↵
~~~~~↵
↵
↵
First, write `mod` using division with remainder
↵
Сначала запишем `mod` через деление с остатком:↵
↵
$$mod = (mod / x) * x + mod \% x$$↵
↵
↵
$$mod \% x = mod - (mod / x) * x$$↵
↵
↵
$$mod \% x\equiv -(mod/x) * x \pmod{mod}$$↵
↵
↵
$$1\equiv -(mod / x) * x * inv(mod \% x) \pmod{mod}$$↵
↵
↵
Dividing both sides by `x`, we get
↵
Разделив обе части на `x`, получаем:↵
↵
$$x^{-1} \equiv -(mod / x) * inv(mod \% x) \pmod{mod}$$↵
↵
↵
$$inv(x) \equiv -(mod / x) * inv(mod \% x) \pmod{mod}$$↵
↵
↵
$$inv(x) \equiv mod - (mod / x) * inv(mod \% x) \pmod{mod}$$↵
↵
↵
~~~~~↵
int inv(int x) {↵
return x == 1 ? 1 : mod - 1LL * (mod / x) * inv(mod % x) % mod;↵
}↵
~~~~~↵
↵
↵



