文章目录
该笔记中主要讲述算法竞赛中常用的数学知识,主要为数论,线性代数,组合数学,概率论,博弈论五个部分。
该笔记中全程用 C++ 语言进行代码讲解。
这里给的例题都会给一道题解,剩下几道练习
制作不易,点个赞吧
- 内容没更新完,敬请期待
质数
定义: 若一个正整数无法被(除了1和它本身)以外的任何自然数除整,则称该数为质数(或素数),否则称该正整数为合数。
素数的分配: 在整个自然数中,质数的数量还是比较少的,对于一个足够大的整数
N
N
N,不超过
N
N
N 的质数大约有
N
/
l
n
N
N/lnN
N/lnN 个,即每个
l
n
N
lnN
lnN 个数中大约有1个质数。
素数的判定:
试除法:
因为一个素数不能被一个除了1和它本身的数除整,那么我们就直接一个一个除,又因为,一个整数
n
n
n 是由一个大于等于
n
\sqrt{n}
n和一个大于等于
n
\sqrt{n}
n 的数组成的,那么我们就可以直接进行时间复杂度为
O
(
n
)
O(\sqrt{n})
O(n) 的计算。
代码实现:
bool isprime(int n)
{
for(int i = 2; i <= n/i; i++)
{
if(n % i== 0) return false;
}
return true;
}
素数的筛选:
素数筛(欧拉筛):
该筛法是算法竞赛中最常用的素数筛法,时间复杂度直接降到了
O
(
n
)
O(n)
O(n) 级别,但空间复杂度就会很高,也是O(n)。
欧拉筛的基本思路是:
- 我们从第一个数字开始找,因为第一个数字2是一个素数,然后就将后面的2的倍数给标记一下,以后将不再遍历,然后再遍历到3 的时候也是一样。
- 因为遍历的时候
代码实现:
bool used[N];
int primes[N];
void isprime()
{
int idx = 0;
for(int i =2 ; i <= N; i++)
{
if(!used[i]) primes[++idx] = i;
for(int j = 1; j <= idx && i * primes[j] <= N; j++)
{
used[i * primes[j]] = true;
if(i % primes[j] == 0) break;
}
}
}
质因数的分解:
算术基本定理:
任何一个大于1的正整数都能唯一分解为有限个质数的乘积,可写作:
N
=
p
1
c
1
p
2
c
2
⋅
⋅
⋅
p
m
c
m
N = p_1^{c_1}p_2^{c_2}···p_m^{c_m}
N=p1c1p2c2⋅⋅⋅pmcm
其中
c
i
c_i
ci 都是正整数,
p
i
p_i
pi 都是质数,且满足
p
1
<
p
2
<
⋅
⋅
⋅
p
m
p_1 < p_2 < ··· p_m
p1<p2<⋅⋅⋅pm。
实现方法:
试除法:
依照素数判定中的试除法进行计算,也是遇到一个数进行相除,直到除到除不整为止。
还有一个比这时间复杂度更少的算法,Pollard-Roh,但是这个比较难,这里就不解释了。
下面就直接看代码
代码实现:
int num[N];
int primes[N];
void divide(int x)
{
int idx = 0;
for(int i = 2; i <= x/i; i++)
{
if(x % i == 0)
primes[++idx] = i,num[idx] = 0;
while(x % i == 0)
{
x /= i;
num[idx] ++;
}
}
if(x > 1)
primes[++idx] = x,num[idx] = 1;
for(int i = 1; i <= idx; i++)
cout << primes[i] << " " << num[i] << endl;
}
例题(题解):
质数距离:
Acwing 196. 质数距离题解
约数
定义:
若一个整数
n
n
n 除以整数
d
d
d 的余数都为
0
0
0,即
d
d
d 能整除
n
n
n,则称
d
d
d 是
n
n
n 的约数,
n
n
n 是
d
d
d 的倍数,记为
d
∣
n
d|n
d∣n。
算术基本定理:
在前面的推论里面解释到,一个正整数
N
N
N 能被唯一分解为
N
=
p
1
c
1
p
2
c
2
⋅
⋅
⋅
p
m
c
m
N = p_1^{c_1}p_2^{c_2}···p_m^{c_m}
N=p1c1p2c2⋅⋅⋅pmcm,其中
c
i
c_i
ci 都是正整数,
p
i
p_i
pi 都是质数,且都满足
p
1
<
p
2
<
p
3
<
⋅
⋅
⋅
<
p
m
p_1 < p_2 < p_3 < ··· < p_m
p1<p2<p3<⋅⋅⋅<pm,则
N
N
N 的正约数集合可写作:
{
p
1
b
1
p
2
b
2
⋅
⋅
⋅
p
m
b
m
}
,其中
0
≤
b
i
≤
c
i
\left\{p_1^{b_1}p_2^{b_2}···p_m^{b_m}\right\},其中 0 \leq b_i \leq c_i
{p1b1p2b2⋅⋅⋅pmbm},其中0≤bi≤ci
所以
N
N
N 的正约数的个数为:(
∏
\prod
∏表示连乘)
(
c
1
+
1
)
×
(
c
2
+
1
)
×
⋅
⋅
⋅
×
(
c
m
+
1
)
=
∏
(
c
i
+
1
)
(c_1 + 1) \times(c_2 + 1) \times···\times (c_m + 1) = \prod(c_i + 1)
(c1+1)×(c2+1)×⋅⋅⋅×(cm+1)=∏(ci+1)
那么约数之和为:
(
1
+
p
1
+
p
1
2
+
⋅
⋅
⋅
+
p
1
c
1
)
×
⋅
⋅
⋅
×
(
1
+
p
m
+
p
m
2
+
⋅
⋅
⋅
+
p
m
c
m
)
=
∏
i
=
1
m
(
∑
j
=
0
c
i
(
p
i
j
)
)
(1 + p_1 + p_1^{2} + ··· + p_1^{c_1}) \times···\times(1 + p_m + p_m^2 + ···+p_m^{c_m}) = \prod_{i=1}^{m}(\sum_{j = 0}^{c_i}(p_i^j))
(1+p1+p12+⋅⋅⋅+p1c1)×⋅⋅⋅×(1+pm+pm2+⋅⋅⋅+pmcm)=i=1∏m(j=0∑ci(pij))
求 N N N的正约数集合的方法:
1. 试除法:
因为一个数是由小于等于
n
\sqrt{n}
n 和大于等于
n
\sqrt{n}
n 的数组成的,那么我们只用遍历前面
2
∼
n
2\sim\sqrt{n}
2∼n的数就行了。
推论:
一个整数
n
n
n 的约数的个数上界为
2
n
2\sqrt{n}
2n。
其他和质因数分解的方法一样,这里就不多说了,直接上代码:
int factor[N];
void divide(int x)
{
int idx = 0;
for(int i = 2; i <= x/i; i++)
{
if(x % i == 0)
{
factor[++idx] = i;
if(i != x / i) factor[++idx] = x/i;
}
}
sort(factor+1,factor + 1+idx);
for(int i = 1; i <= idx; i++)
cout << factor[i] << " ";
}
2. 倍数法:
如果用 “试除法” 求
1
∼
n
1 \sim n
1∼n中每个数的正约数集合,那么时间复杂度就为
O
(
N
N
)
O(N\sqrt{N})
O(NN),时间很长,那么反过来考虑的话,我们可以用倍增的方法进行求每个数
d
d
d ,
1
∼
N
1 \sim N
1∼N 中以
d
d
d 为约数的数就是
d
d
d 的倍数,那么我们就考虑,用倍增的方法进行求倍数,可以减少很多重复的操作。
时间复杂度为:
O
(
N
+
N
/
2
+
N
/
3
+
⋅
⋅
⋅
+
N
/
N
)
=
O
(
N
log
N
)
O(N + N/2 + N/3 +···+ N / N) = O(N \log{N})
O(N+N/2+N/3+⋅⋅⋅+N/N)=O(NlogN)
代码实现:
void divide(int x)
{
vector<int> factor[50005];
for(int i =1 ; i <= x; i++)
for(int j = 1; j <= x / i; j++)
factor[i * j].push_back(i);
for(int i =1 ; i <= x; i++)
{
for (int j : factor[i]) {
cout << j << " ";
}
cout << endl;
}
}
最大公约数:
定义:
最大公约数:
若自然数 d d d 同时是自然数 a a a 和 b b b 的约数,则称 d d d 是 a a a 和 b b b 的公约数,在所有 a a a 和 b b b 的公约数中最大的一个则称为 a a a 和 b b b 的最大公约数,记为 g c d ( a , b ) gcd(a,b) gcd(a,b)。
最小公倍数:
若自然数 m m m 同时是自然数 a a a 和 b b b 的倍数,则称 m m m 是 a a a和 b b b的公倍数,在所有 a a a 和 b b b的公倍数中最小的那个就叫做最小公倍数, 记为 l c m ( a , b ) lcm(a,b) lcm(a,b).
同理,我们可以定义三个数以及更多个数的最大公约数、最小公倍数。
定理:
∀
a
,
b
∈
N
,
g
c
d
(
a
,
b
)
×
l
c
m
(
a
,
b
)
=
a
×
b
\forall a,b \in N,gcd(a,b) \times lcm(a,b) = a \times b
∀a,b∈N,gcd(a,b)×lcm(a,b)=a×b
计算最大公约数:
九章算术·更相减损术:
- ∀ a , b ∈ N , a ≥ b , 有 g c d ( a , b ) = g c d ( b , a − b ) = g c d ( a , a − b ) \forall a,b \in N,a \geq b,有 gcd(a,b) = gcd(b,a-b) = gcd(a,a-b) ∀a,b∈N,a≥b,有gcd(a,b)=gcd(b,a−b)=gcd(a,a−b)
- ∀ a , b ∈ N , 有 g c d ( 2 a , 2 b ) = 2 g c d ( a , b ) \forall a,b \in N,有 gcd(2a,2b) = 2 gcd(a,b) ∀a,b∈N,有gcd(2a,2b)=2gcd(a,b)]
代码实现:
int gcd(int a,int b)
{
int t = abs(a-b);
while(t)
{
a = b;
b = t;
t = abs(a - b);
}
return b;
}
欧几里得算法:
∀
a
,
b
∈
N
,
b
≠
0
,
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
\forall a,b\in N,b \ne 0 ,gcd(a,b) = gcd(b,a \bmod b)
∀a,b∈N,b=0,gcd(a,b)=gcd(b,amodb)
代码实现:
int gcd(int a, int b) {
return b ? gcd(b,a%b):a;
}
注意事项:
对于欧几里得算法的时间复杂度为:
O
(
log
(
a
+
b
)
)
O(\log(a + b))
O(log(a+b))
欧几里得算法是最常用的求最大公约数的方法,不过对于高精度除法(取模)不容易实现,需要高精度的时候可以考虑用更相减损术代替欧几里得算法。
互质与欧拉函数:
定义:
∀
a
,
b
∈
N
,
若
g
c
d
(
a
,
b
)
=
1
,则称
a
,
b
互质
\forall a,b \in N,若gcd(a,b) = 1,则称 a,b 互质
∀a,b∈N,若gcd(a,b)=1,则称a,b互质
对于三个数或者更多个数的情况,我们把 g c d ( a , b , c ) = 1 gcd(a,b,c) = 1 gcd(a,b,c)=1 的情况称为 a , b , c a,b,c a,b,c 互质数。把 g c d ( a , b ) = g c d ( b , c ) = g c d ( a , c ) = 1 gcd(a,b) = gcd(b,c) = gcd(a,c) = 1 gcd(a,b)=gcd(b,c)=gcd(a,c)=1 称为两两互质。后者显然是一个更强的条件。
欧拉函数:
定义:
1
∼
N
中与
N
互质的数的个数被称为欧拉函数,记为
φ
(
N
)
。
1 \sim N 中与 N 互质的数的个数被称为欧拉函数,记为\varphi(N)。
1∼N中与N互质的数的个数被称为欧拉函数,记为φ(N)。
在算术基本定理中,
N
=
p
1
c
1
p
2
c
2
⋅
⋅
⋅
p
m
c
m
N = p_1^{c_1}p_2^{c_2}···p_m^{c_m}
N=p1c1p2c2⋅⋅⋅pmcm,则:
φ
(
N
)
=
N
∗
p
1
−
1
p
1
∗
p
2
−
1
p
2
∗
⋅
⋅
⋅
∗
p
m
−
1
p
m
=
N
∗
∏
质数
p
∣
N
(
1
−
1
p
)
\varphi(N) = N * \frac{p_1 - 1}{p_1} * \frac{p_2-1}{p_2}*···*\frac{p_m-1}{p_m} = N * \prod_{质数p|N}(1-\frac{1}{p})
φ(N)=N∗p1p1−1∗p2p2−1∗⋅⋅⋅∗pmpm−1=N∗质数p∣N∏(1−p1)
证明:
设 p p p 是 N N N 的质因子, 1 ∼ N 1 \sim N 1∼N 中 p p p 的倍数有 p , 2 p , 3 p , ⋅ ⋅ ⋅ , ( N / p ) ∗ p p,2p,3p,···,(N/p)*p p,2p,3p,⋅⋅⋅,(N/p)∗p,共 N / p N/p N/p 个。设 q q q 是 N N N 的质因子, 1 ∼ N 1 \sim N 1∼N 中 q q q 的倍数有 q , 2 q , 3 q , ⋅ ⋅ ⋅ , ( N / q ) ∗ q q,2q,3q,···,(N/q)*q q,2q,3q,⋅⋅⋅,(N/q)∗q,共 N / q N/q N/q 个。如果我们将 N / p + N / q N/p + N/q N/p+N/q 的个数去掉,那么 p ∗ q p*q p∗q 的倍数就被排除了两次,需要再加回来。因此, 1 ∼ N 1 \sim N 1∼N 中与 N N N 含有共同质因子 p p p 或 q q q 的个数就为:
N − N p − N q + N p q = N ∗ ( 1 − 1 p − 1 q + 1 p q ) = N ∗ ( 1 − 1 p ) ( 1 − 1 q ) N - \frac{N}{p} - \frac{N}{q} + \frac{N}{pq} = N * (1 - \frac{1}{p} - \frac{1}{q} + \frac{1}{pq}) = N*(1-\frac{1}{p})(1-\frac{1}{q}) N−pN−qN+pqN=N∗(1−p1−q1+pq1)=N∗(1−p1)(1−q1)
实际上,上述思想被称为容斥原理,类似的,可以再 N N N 的全部质因子上使用容斥原理,即可得到像上述的公式。
根据欧拉函数的计算式,我们只需要分解质因数,即可顺便求出欧拉函数。
代码实现:
试除法求一个整数
N
N
N 的欧拉函数值:
int phi(int n)
{
int ans = n;
for(int i = 2; i <= n/i; i++)
{
if(n % i == 0)
{
ans = ans/ i * (i - 1);
while(n % i == 0)
n /= i;
}
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
也可以用线性筛的方法求
1
∼
N
1 \sim N
1∼N之间的每个数的欧拉函数:
讲解写在另一个博客中了,不懂的可以去翻看
线性筛求欧拉函数
void phi(int x)
{
cnt = 0;
phis[1] = 1;
for(int i = 2; i <= x; i++)
{
if(!used[i])
{
phis[i] = i-1;
primes[++cnt] = i;
}
for(int j = 1; i * primes[j] <= x; j++)
{
used[i * primes[j]] = true;
if(i % primes[j] == 0)
{
phis[i * primes[j]] = primes[j] * phis[i];
break;
}
phis[i * primes[j]] = (primes[j] - 1) * phis[i];
}
}
}
性质:
- ∀ n > 1 , 1 ∼ n \forall n > 1,1 \sim n ∀n>1,1∼n 中与 n n n 互质的数的和为 n ∗ φ ( n ) / 2 {n * \varphi (n)}/{2} n∗φ(n)/2。
证明:因为 g c d ( n , x ) = g c d ( n , n − x ) gcd(n,x) = gcd(n,n-x) gcd(n,x)=gcd(n,n−x),所以与 n n n 不互质的数 x , n − x x,n-x x,n−x都是成对存在的,平均值为 n/2。因此,与 n n n 互质的数的平均值也是 n / 2 n/2 n/2,进而得出性质1。
- 若 a , b a,b a,b 互质,则 φ ( a b ) = φ ( a ) φ ( b ) \varphi(ab) = \varphi(a)\varphi(b) φ(ab)=φ(a)φ(b)。
证明:根据欧拉函数的计算式,对 a a a, b b b 分解质因数,直接可得到性质2,把性质2推广到一般的函数中,就可以得到 积性函数
- 积性函数:如果当 a , b a,b a,b 互质时,有 f ( a b ) = f ( a ) ∗ f ( b ) f(ab) = f(a) * f(b) f(ab)=f(a)∗f(b),那么称函数 f f f 为积性函数。
- 若 f f f 是积性函数,且在算术基本定理中 n = ∏ i = 1 m p i c i n = \prod_{i=1}^{m}p_i^{c_i} n=∏i=1mpici,则 f ( n ) = ∏ i = 1 m f ( p i c i ) f(n) = \prod_{i=1}^{m}f(p_i^{c_i}) f(n)=∏i=1mf(pici)。
证明:把 n n n 分解质因子,按照积性函数的定义,性质4显然是正确的。
- 设 p p p 为质数,若 p ∣ n p|n p∣n 且 p 2 ∣ n p^2\mid n p2∣n,则 φ ( n ) = φ ( n / p ) ∗ p \varphi(n) = \varphi(n/p)*p φ(n)=φ(n/p)∗p。
证明:若 p ∣ n p\mid n p∣n 且 p 2 ∣ n p^2 \mid n p2∣n,则 n , n / p n,n/p n,n/p 包含相同的质因子,只是 p p p 的指数不同。直接按照欧拉函数将 φ ( n ) \varphi(n) φ(n) 和 φ ( n / p ) \varphi(n/p) φ(n/p) 计算出来,然后进行相除,得到的就是 p。
- 设 p p p 为质数,若 p ∣ n p|n p∣n 且 p 2 ∤ n p^2 \not \mid n p2∣n,则 φ ( n ) = φ ( n / p ) ∗ ( p − 1 ) \varphi(n) = \varphi(n/p)*(p-1) φ(n)=φ(n/p)∗(p−1)。
证明:若 p ∣ n p \mid n p∣n 且 p 2 ∤ n p^2 \not\mid n p2∣n,说明 p , n / p p,n/p p,n/p 互质,因为 φ \varphi φ是积性函数,所以 φ ( n ) = φ ( n / p ) ∗ φ ( n ) \varphi(n) = \varphi(n/p) * \varphi(n) φ(n)=φ(n/p)∗φ(n),而 φ ( p ) = p − 1 \varphi(p) = p - 1 φ(p)=p−1。
- ∑ d ∣ n φ ( d ) = n \sum_{d\mid n}\varphi(d) = n ∑d∣nφ(d)=n
证明:设 f ( n ) = ∑ d ∣ n φ ( d ) f(n) = \sum_{d\mid n}\varphi(d) f(n)=∑d∣nφ(d)。用乘法分配律展开比较,再利用 φ \varphi φ 是积性函数,得到:若 n , m n,m n,m 互质,那么 f ( n m ) = ∑ d ∣ n φ ( d ) = ( ∑ d ∣ n φ ( d ) ) ∗ ( ∑ d ∣ n φ ( n ) ) = f ( n ) ∗ f ( m ) f(nm) = \sum_{d \mid n}\varphi(d) = (\sum_{d\mid n}\varphi(d)) * (\sum_{d\mid n}\varphi(n)) = f(n) * f(m) f(nm)=∑d∣nφ(d)=(∑d∣nφ(d))∗(∑d∣nφ(n))=f(n)∗f(m)。即 ∑ d ∣ n φ ( d ) \sum_{d\mid n}\varphi(d) ∑d∣nφ(d) 是积性函数。对于单个质因子, f ( p m ) = ∑ d ∣ p m φ ( d ) = φ ( 1 ) + φ ( p ) + φ ( p 2 ) + ⋅ ⋅ ⋅ + φ ( p m ) f(p^m) = \sum_{d\mid p^m}\varphi(d) =\varphi(1) + \varphi(p) + \varphi(p^2)+···+\varphi(p^m) f(pm)=∑d∣pmφ(d)=φ(1)+φ(p)+φ(p2)+⋅⋅⋅+φ(pm) 是一个等比数列求和数列求和再加1,结果为 p m p^m pm。所以 f ( n ) = ∑ i = 1 m f ( p i c i ) = ∏ i = 1 m p i c i = n f(n) = \sum_{i=1}^mf(p_i^{c_i}) = \prod_{i=1}^{m}p_i^{c_i} = n f(n)=∑i=1mf(pici)=∏i=1mpici=n。
例题(题解):
反素数(约数):
AcWing 198. 反素数题解
Hankson的趣味题(最大公约数):
Acwing 200. Hankson的趣味题题解
可见的点(互质与欧拉函数):
Acwing 201. 可见的点题解
扩展
蓝桥杯-3522 互质数的个数
同余
定义:
若整数
a
a
a 和整数
b
b
b 除以正整数
m
m
m的余数相等,则称
a
,
b
a,b
a,b 模
m
m
m 同余,则记为
a
≡
b
(
m
o
d
m
)
a \equiv b(\mod m)
a≡b(modm)。
同余与剩余系:
对于
∀
a
∈
[
0
,
m
−
1
]
\forall a \in [0,m-1]
∀a∈[0,m−1],集合
a
+
k
m
(
k
∈
Z
)
{a + km}(k\in Z)
a+km(k∈Z) 的所有数模
m
m
m 同余,余数都是
a
a
a。该集合称为一个模
m
m
m 的同余类,简称为
a
ˉ
\bar{a}
aˉ
模
m
m
m 的同余类一共有
m
m
m 个,分别为
0
ˉ
,
1
ˉ
,
2
ˉ
.
.
.
m
−
1
‾
\bar{0},\bar{1},\bar{2}...\overline{m-1}
0ˉ,1ˉ,2ˉ...m−1。它们构成
m
m
m 的完全剩余系。
模
1
∼
m
1\sim m
1∼m 中与
m
m
m 互质的数代表的同余类共有
φ
(
m
)
\varphi(m)
φ(m)个,它们构成
m
m
m 的简化剩余系,例如:模 10 的简化剩余系为
{
1
ˉ
,
3
ˉ
,
7
ˉ
,
9
ˉ
}
\left\{\bar{1},\bar{3},\bar{7},\bar{9}\right\}
{1ˉ,3ˉ,7ˉ,9ˉ}。
简化剩余系关于模
m
m
m 乘法封闭(一个集合中任意两个元素相乘还是在这个集合中)。这是因为若
a
,
b
(
1
≤
a
,
b
≤
m
)
a,b(1 \leq a,b \leq m)
a,b(1≤a,b≤m) 与
m
m
m 互质,则
a
∗
b
a * b
a∗b也不可能与
m
m
m 含有相同的质因子,即
a
∗
b
a * b
a∗b 也与
m
m
m 互质。再由余数的定义即可得到
a
∗
b
m
o
d
m
a * b \mod m
a∗bmodm 也与
m
m
m 互质。既
a
∗
b
m
o
d
m
a * b \mod m
a∗bmodm 也属于
m
m
m 的简化剩余系。
费马小定理:
若 p p p 是质数,则对于任何整数 a a a,有 a p ≡ 1 ( m o d n ) a^p \equiv 1(\mod n) ap≡1(modn),其中 φ ( n ) \varphi(n) φ(n)为欧拉函数。
欧拉定理:
若正整数 a , n a,n a,n 互质,则 a φ ( n ) = 1 ( m o d n ) a^{\varphi(n)} = 1 (\mod n) aφ(n)=1(modn),其中 φ ( n ) \varphi(n) φ(n) 为欧拉函数。
证明:
设 n n n 的简化剩余系为 { a 1 ‾ , a 2 ‾ . . . , a φ n ‾ } \left\{\overline{a_1},\overline{a_2}...,\overline{a_{\varphi{n}}}\right\} {a1,a2...,aφn}。对 ∀ a i , a j \forall a_i,a_j ∀ai,aj,若 a ∗ a i ≡ a ∗ a j ( m o d n ) a * a_i \equiv a * a_j(\mod n) a∗ai≡a∗aj(modn),则 a ∗ ( a i − a j ) ≡ 0 a * (a_i-a_j) \equiv0 a∗(ai−aj)≡0。因为 a , n a,n a,n 互为质数,所以 a i − a j ≡ 0 a_i - a_j \equiv 0 ai−aj≡0,即 a i ≡ a j a_i \equiv a_j ai≡aj。故当 a i ≠ a j a_i \ne a_j ai=aj 时, a a i , a a j aa_i,aa_j aai,aaj 也代表不同的同余类。
又因为简化剩余系关于模 n n n 乘法封闭,故 a a i ‾ \overline{aa_i} aai也在简化剩余系集合中,因此,集合 { a 1 ‾ , a 2 ‾ , . . . , a φ ( n ) ‾ } \left\{\overline{a_1},\overline{a_2},...,\overline{a_{\varphi(n)}}\right\} {a1,a2,...,aφ(n)} 与集合 { a a 1 ‾ , a a 2 ‾ , . . . , a a φ ( n ) ‾ } \left\{\overline{aa_1},\overline{aa_2},...,\overline{aa_{\varphi(n)}}\right\} {aa1,aa2,...,aaφ(n)}都能表示 n n n 的简化剩余系。综上所诉:
a φ ( n ) a 1 a 2 . . . a φ n ≡ ( a a 1 ) ( a a 2 ) . . . ( a a φ ( n ) ) ≡ a 1 a 2 . . . a φ ( n ) ( m o d n ) a^{\varphi(n)}a_1a_2...a_{\varphi{n}} \equiv(aa_1)(aa_2)...(aa_{\varphi(n)}) \equiv a_1a_2...a_{\varphi(n)} (\mod n) aφ(n)a1a2...aφn≡(aa1)(aa2)...(aaφ(n))≡a1a2...aφ(n)(modn)
因此
a
φ
(
n
)
≡
1
(
m
o
d
n
)
a^{\varphi(n)} \equiv1 (\mod n)
aφ(n)≡1(modn)。
当
p
p
p 是质数时,
φ
(
p
)
=
p
−
1
\varphi(p) = p - 1
φ(p)=p−1,并且只有
p
p
p 的倍数与
p
p
p 不互质。所以,只要
a
a
a 不是
p
p
p 的倍数,就有
a
p
−
1
≡
1
(
m
o
d
n
)
a^{p-1} \equiv 1(\mod n)
ap−1≡1(modn),两边同乘
a
a
a 就是费马小定理。另外,若
a
a
a 是
p
p
p 的倍数,费马小定理显然成立。
证毕。
证明:
设 b = q ∗ φ ( n ) + r b = q * \varphi(n) + r b=q∗φ(n)+r,其中 0 ≤ r < φ ( n ) 0 \leq r < \varphi(n) 0≤r<φ(n),即 r = b m o d φ ( n ) r = b \mod \varphi(n) r=bmodφ(n)。于是:
a b ≡ a p ∗ φ ( n ) + r ≡ ( a φ ( n ) ) q ∗ a r ≡ 1 q ∗ a r ≡ a r ≡ a b m o d φ ( n ) ( m o d n ) a^b \equiv a^{p * {\varphi(n)} + r} \equiv (a^{\varphi(n)})^q * a^r \equiv1^q * a^r \equiv a^r \equiv a^{b \mod \varphi(n)}(\mod n) ab≡ap∗φ(n)+r≡(aφ(n))q∗ar≡1q∗ar≡ar≡abmodφ(n)(modn)
证毕。
许多计数类的题目要求我们把答案对一个质数
p
p
p 取模后输出。面对
a
+
b
,
a
−
b
,
a
∗
b
a + b,a-b,a*b
a+b,a−b,a∗b 这样的算式,可以在计算前把
a
,
b
a,b
a,b对
p
p
p取模,面对乘方算式,根据欧拉定理的推论,可以先把底数对p取模、指数对
φ
(
p
)
\varphi(p)
φ(p)取模,再计算乘方。
- 当 a , n a,n a,n不一定互质且 b > φ ( n ) 时,有 a b ≡ a b m o d φ ( n ) + φ ( n ) m o d n b>\varphi(n)时,有a^b \equiv a^{b mod \varphi(n) + \varphi(n)} mod n b>φ(n)时,有ab≡abmodφ(n)+φ(n)modn