逆元
定义
一个数 a a a的倒数 a − 1 a^{-1} a−1满足 a × a − 1 = 1 a \times a^{-1} = 1 a×a−1=1。取 a a a的逆元 ( a m o d    b ) − 1 (a \mod b)^{-1} (amodb)−1满足 ( a m o d    b ) × ( a m o d    b ) − 1 m o d    b = 1 (a \mod b) \times (a \mod b)^{-1} \mod b = 1 (amodb)×(amodb)−1modb=1。其中 b b b为质数, a a a的逆元 ( a m o d    b ) − 1 = a b − 2 m o d    b (a \mod b)^{-1} = a^{b-2} \mod b (amodb)−1=ab−2modb。
证明
由费马小定理得
a
b
−
1
m
o
d
  
b
=
1
a^{b-1} \mod b = 1
ab−1modb=1,即
(
a
b
−
2
m
o
d
  
b
)
×
(
a
m
o
d
  
b
)
m
o
d
  
b
=
1
(a^{b-2} \mod b) \times (a \mod b) \mod b = 1
(ab−2modb)×(amodb)modb=1,故
(
a
m
o
d
  
b
)
−
1
=
a
b
−
2
m
o
d
  
b
(a \mod b)^{-1} = a^{b-2} \mod b
(amodb)−1=ab−2modb。
费马小定理简单证明如下:取
A
=
{
1
,
2
,
…
,
b
−
1
}
A = \{1,2, \dots ,b-1\}
A={1,2,…,b−1},则
A
m
o
d
  
b
=
{
1
,
2
,
…
,
b
−
1
}
A \mod b = \{1,2, \dots ,b-1\}
Amodb={1,2,…,b−1};取
a
×
A
=
{
a
,
2
a
,
…
,
(
b
−
1
)
a
}
a \times A = \{a,2a, \dots, (b-1)a\}
a×A={a,2a,…,(b−1)a},则
a
×
A
m
o
d
  
b
=
{
1
,
2
,
…
,
b
−
1
}
a \times A \mod b = \{1,2, \dots ,b-1\}
a×Amodb={1,2,…,b−1}仍然成立(此处可见下面证明)。取
A
A
A中所有元素相乘得
S
S
S,取
a
×
A
a \times A
a×A中所有元素相乘得
a
b
−
1
×
S
a^{b-1} \times S
ab−1×S,由
{
S
m
o
d
  
b
=
(
b
−
1
)
!
m
o
d
  
b
a
b
−
1
×
S
m
o
d
  
b
=
(
b
−
1
)
!
m
o
d
  
b
\left\{\begin{array}{cc} S \mod b = (b-1)! \mod b\\ a^{b-1} \times S \mod b = (b-1)! \mod b \end{array}\right.
{Smodb=(b−1)!modbab−1×Smodb=(b−1)!modb得
a
b
−
1
m
o
d
  
b
=
1
a^{b-1} \mod b = 1
ab−1modb=1。
下面用反证法证明
a
×
A
m
o
d
  
b
=
{
1
,
2
,
…
,
b
−
1
}
a \times A \mod b = \{1,2, \dots ,b-1\}
a×Amodb={1,2,…,b−1}。对于任意
x
,
y
∈
a
×
A
,
x
<
y
x,y \in a \times A, x \lt y
x,y∈a×A,x<y,假设
x
m
o
d
  
b
=
y
m
o
d
  
b
x \mod b = y \mod b
xmodb=ymodb,那么
(
y
−
x
)
m
o
d
  
b
=
0
(y-x) \mod b = 0
(y−x)modb=0,由
{
y
m
o
d
  
a
=
0
x
m
o
d
  
a
=
0
\left\{\begin{array}{cc} y \mod a = 0\\ x \mod a = 0 \end{array}\right.
{ymoda=0xmoda=0得
(
y
−
x
)
m
o
d
  
a
=
0
(y-x) \mod a = 0
(y−x)moda=0,由
b
b
b为质数得
l
c
m
(
a
,
b
)
=
a
×
b
lcm(a, b) = a \times b
lcm(a,b)=a×b,故
(
y
−
x
)
m
o
d
  
(
a
×
b
)
=
0
(y-x) \mod (a \times b) = 0
(y−x)mod(a×b)=0,因此
y
−
x
≥
a
×
b
y-x \ge a \times b
y−x≥a×b,与
x
,
y
∈
a
×
A
x,y \in a \times A
x,y∈a×A矛盾,由此可得
x
m
o
d
  
b
≠
y
m
o
d
  
b
x \mod b \ne y \mod b
xmodb̸=ymodb。因此
a
×
A
m
o
d
  
b
a \times A \mod b
a×Amodb有
(
b
−
1
)
(b-1)
(b−1)个互不相同的元素,即
a
×
A
m
o
d
  
b
=
{
1
,
2
,
…
,
b
−
1
}
a \times A \mod b = \{1,2, \dots ,b-1\}
a×Amodb={1,2,…,b−1}。
思路
利用快速幂求 a a a的逆元 a b − 2 m o d    b a^{b-2} \mod b ab−2modb。
时间复杂度
O ( log n ) O(\log n) O(logn)
模板
#include "FP.h"
typedef long long LL;
const LL MOD = 1e9+7; // the divisor of answer
/**
* @param a: the number a
* @return: the inverse of a
* @other: FP is Fast Power
*/
LL INV(LL a) {
return FP(a, MOD-2);
}
应用1
求组合数 C n m m o d    b C_n^m \mod b Cnmmodb。由 C n m = n ! m ! ( n − m ) ! C_n^m = \frac {n!}{m!(n-m)!} Cnm=m!(n−m)!n!得 C n m m o d    b = n ! m ! ( n − m ) ! m o d    b = ( n ! m o d    b ) × ( m ! m o d    b ) − 1 × ( ( n − m ) ! m o d    b ) − 1 m o d    b C_n^{m} \mod b = \frac {n!}{m!(n-m)!} \mod b = (n! \mod b) \times (m! \mod b)^{-1}\times((n-m)! \mod b)^{-1}\mod b Cnmmodb=m!(n−m)!n!modb=(n!modb)×(m!modb)−1×((n−m)!modb)−1modb。先预处理 1 ! , 2 ! , … , n ! 1!,2!,\dots,n! 1!,2!,…,n!,时间复杂度为 O ( n ) O(n) O(n),再直接求 C n m m o d    b C_n^m \mod b Cnmmodb,时间复杂度为 O ( 1 ) O(1) O(1)。
模板1
#include "INV.h"
const LL N = 1e6+10; // the maximum number
LL fac[N]; // the factorial of numbers
LL inv[N]; // the inverse of factorial
/**
* @other: initialize fac and inv
*/
void init() {
inv[0] = fac[0] = 1; // 0! = 1, INV(1) = 1
for (int i = 1; i < N; ++i) {
fac[i] = fac[i-1] * i % MOD; // i! = (i-1)! * i
inv[i] = INV(fac[i]);
}
}
/**
* @param n: the number n
* @param m: the number m
* @return: C(n, m)
*/
LL C(LL n, LL m) {
return fac[n] * inv[m] % MOD * inv[n-m] % MOD;
}
应用2
已知 p , q , b p,q,b p,q,b,求 a a a满足 a × p m o d    b = q m o d    b a \times p \mod b = q \mod b a×pmodb=qmodb。由 ( a × p m o d    b ) × ( p m o d    b ) − 1 = ( q m o d    b ) × ( p m o d    b ) − 1 (a \times p \mod b) \times (p \mod b)^{-1} = (q \mod b) \times (p \mod b)^{-1} (a×pmodb)×(pmodb)−1=(qmodb)×(pmodb)−1得 a = ( q m o d    b ) × ( p m o d    b ) − 1 a = (q \mod b) \times (p \mod b)^{-1} a=(qmodb)×(pmodb)−1。
模板2
#include "INV.h"
/**
* @param p: the number p
* @param q: the number q
* @return: the number a
*/
LL cal(LL p, LL q) {
return q * INV(p) % MOD;
}