# 【数论】乘法逆元

## Definition

$x \times y \equiv 1 \pmod p$

## Algorithm

#### Proof

$x \times x^{-1} \equiv 1 \pmod p~~~~~~(1)$

$\gcd(x,~p) = d \neq 1~~~~~~(2)$

$x \times x^{-1} = k \times p + 1~~~~~~(3)$

$(3)$ 的等号两侧同时除以 $(2)$ 中的 $d$

$\frac{x \times x^{-1}}{d}~=~\frac{k \times p + 1}{d}~~~~~~(4)$

$\frac{x}{d} \times x^{-1}~=~\frac{p}{d} \times k + \frac{1}{d}~~~~~~(5)$

$\frac{x}{d}$$\frac{p}{d}$ 都是整数，进而 $\frac{p}{d} \times k$ 是整数，$\frac{x}{d} \times x^{-1}$ 是整数。

#### 求单个数字的逆元

##### Algorithm 1

$x \times x^{-1}~\equiv 1 \pmod p$

$x \times x^-1 = 1 + kp$

$y = -k$，移项得到

$x \times x^{-1} + y \times p = 1$

$ax + by = 1$

##### Algorithm 2

$x^{\phi(p)} \equiv 1 \pmod p$

$x^{\phi(p) - 1} \equiv x^{-1} \pmod p$

#### 求 $n$ 以内所有正整数模 $p$ 的逆元

$inv_i \equiv \left\lfloor\frac{p}{i}\right\rfloor \times inv_{p \bmod i} \pmod p$

$inv_1 = 1$

##### Proof

$p = ki + r$

$0 \equiv ki + r \pmod p$

$r \equiv -ki \pmod p$

$i^{-1} \equiv -kr^{-1} \pmod p$

## Code

### Ex_Gcd

#include <iostream>

typedef long long int ll;

ll x, p;

void Ex_gcd(const ll a, const ll b, ll &X, ll &Y);

int main() {
std::cin >> x >> p;
ll a, b;
Ex_gcd(x, p, a, b);
std::cout << (a % p + p) % p << std::endl;
return 0;
}

void Ex_gcd(const ll a, const ll b, ll &X, ll &Y) {
if (b == 0) {
X = 1; Y = 0;
} else {
Ex_gcd(b, a % b, Y, X);
Y -= a / b * X;
}
}


### 欧拉定理

#include <iostream>

typedef long long int ll;

ll X, p;

ll mpow(ll x, ll y);

int main() {
std::cin >> X >> p;
std::cout << mpow(X, p - 2) << std::endl;
return 0;
}

ll mpow(ll x, ll y) {
ll _ret = 1;
while (y) {
if (y & 1) (_ret *= x) %= p;
y >>= 1;
(x *= x) %= p;
}
return _ret;
}


### 线性求逆元

#include <cstdio>

const int maxn = 3000005;

int n, p;
int inv[maxn], factinv[maxn];

int main() {
scanf("%d%d", &n, &p);
factinv[1] = inv[1] = 1;
printf("%d\n", 1);
for (int i = 2; i <= n; ++i) {
inv[i] = 1ll * (p - p / i) * inv[p % i] % p;
printf("%d\n", inv[i]);
factinv[i] = 1ll * factinv[i - 1] * inv[i] % p;
}
return 0;
}

posted @ 2020-01-06 20:29  一扶苏一  阅读(470)  评论(0编辑  收藏  举报