数论,是一门研究整数的纯数学的分支,而整数的基本元素是素数(也称质数),所以数论的本质是对素数性质的研究。
素数
一些基本概念就不写了.
注意两点:
0、1、负整数 既不是素数也不是合数.
π ( n ) \pi(n) π ( n ) 表示不大于 n n n 的素数个数, 有如下近似关系 π ( n ) ∼ n ln n \pi(n)\sim\dfrac{n}{\ln{n}} π ( n ) ∼ ln n n .
素数判定
如何判定正整数 n n n 是否是素数?
很容易想到用每一个小于 n n n 且大于 1 1 1 的数来判断它是否是 n n n 的约数, 若都不是, 则 n n n 为素数, 否则为合数.
这个暴力算法是 O ( n ) \mathcal{O}(n) O ( n ) 的, 但是我们考虑到, 若数 p p p 为 n n n 的约数, 则 n p \frac{n}{p} p n 也是 n n n 的约数, 所以我们只需用 2 ∼ n 2\sim \sqrt{n} 2 ∼ n 的数来判定即可, 于是优化一下我们得到一个 O ( n ) \mathcal{O}(\sqrt{n}) O ( n ) 的算法.
1 2 3 4 5 6 7 bool isPrime (int n) { if (n == 1 ) return false ; if (n == 2 ) return true ; for (int i = 2 ; i * i <= n; ++i) if (n % i == 0 ) return false ; return true ; }
整数惟一分解定理
若整数 n ≥ 2 n\ge2 n ≥ 2 , 那么 n n n 一定可以惟一地表示为若干素数的乘积, 形如
n = p 1 r 1 p 2 r 2 ⋯ p k r k ( p i 为素数 , r i ≥ 0 ) n=p_1^{r_1}p_2^{r_2}\cdots p_k^{r_k}(p_i为素数, r_i\ge0)
n = p 1 r 1 p 2 r 2 ⋯ p k r k ( p i 为 素 数 , r i ≥ 0 )
1 2 3 4 5 6 7 8 9 10 vector <int > factor (int n) { vector <int > ret; for (int i = 2 ; i * i <= n; ++i) while (n % i == 0 ) { ret.push_back (i); n /= i; } if (n > 1 ) ret.push_back (n); return ret; }
素数筛法
主要是埃氏筛法和欧拉筛法.
Eratosthenes 筛法
Eratosthenes 筛法可以快速列举出给定范围内的所有素数.
一个合数一定可以写成 p ⋅ x p\cdot x p ⋅ x 的形式, 其中 p p p 为素数, x x x 为整数, 因此对每一个 p p p , 我们从小到大枚举 x x x , 筛掉相应的 p ⋅ x p\cdot x p ⋅ x 即可.
一点小改进: 当 x < p x<p x < p 时, p ⋅ x p\cdot x p ⋅ x 一定被 x x x 的素因子筛过一遍, 所以我们枚举 x x x 时从 x = p x=p x = p 开始枚举.
时间复杂度: O ( n 2 + n 3 + n 5 + ⋯ ) = O ( n log log n ) \mathcal{O}(\frac{n}{2}+\frac{n}{3}+\frac{n}{5}+\cdots)=\mathcal{O}(n\log{\log{n}}) O ( 2 n + 3 n + 5 n + ⋯ ) = O ( n log log n )
1 2 3 4 5 6 7 8 9 10 11 bool isprime[N];void Eratos (int n) { memset (isprime, 1 , sizeof isprime); isprime[0 ] = isprime[1 ] = 0 ; for (int i = 2 ; i * i <= n; ++i) if (isprime[i]) { for (int j = i * i; j <= n; j += i) isprime[j] = 0 ; } }
例题
「POJ 2689」Prime Distance
由于这里 L , R L,R L , R 的范围很大, 暴力筛完之后枚举求解肯定会 T , 但是 R − L ≤ 1 0 6 R-L\le 10^6 R − L ≤ 1 0 6 的范围却是在我们的承受范围之内的.
于是我们考虑用 1 ∼ n 1\sim n 1 ∼ n 这一小范围的素数筛掉 L ∼ R L\sim R L ∼ R 之间的合数.
假设数 k ∈ [ L , R ] k\in[L, R] k ∈ [ L , R ] , 其中 k k k 的最小质因数为 p p p , 满足 p > n p>n p > n , 则 k = p ⋅ x k=p\cdot x k = p ⋅ x , 若 x < p x<p x < p , 则 k k k 一定存在小于 p p p 的质因数, 矛盾, 故而 x ≥ p x\ge p x ≥ p , 也就是说, 会被漏筛的数 k k k 满足 k ≥ p 2 k\ge p^2 k ≥ p 2 , 为了保证算法的正确性, 我们要让这样的数落在 [ L , R ] [L, R] [ L , R ] 外, 也就是让 p 2 > R p^2>R p 2 > R , 于是我们令 n = R n=\sqrt{R} n = R 即可.
筛法优化质因数分解
利用埃氏筛法可以快速实现素因数分解, 只要在筛的时候记录下每个数的最小素因数即可.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 bool isprime[N];int minfac[N];void Eratos (int n) { memset (isprime, 1 , sizeof isprime); isprime[0 ] = isprime[1 ] = 0 ; for (int i = 1 ; i <= n; ++i) minfac[i] = i; for (int i = 2 ; i * i <= n; ++i) if (isprime[i]) { for (int j = i * i; j <= n; j += i) { isprime[j] = 0 ; if (minfac[j] == j) minfac[j] = i; } } } vector <int > factor (int n) { vector <int > ret; while (n > 1 ) { ret.push_back (minfac[n]); n /= minfac[n]; } return ret; }
Euler 筛法
在埃氏筛中, 30 这个数被 p = 2 , 3 , 5 p=2,3,5 p = 2 , 3 , 5 分别筛了三次, 造成了重复, 如果我们能让每个数只被它最小的素因数筛, 就能做到 O ( n ) \mathcal{O}(n) O ( n ) 的时间复杂度.
在 Euler 筛法中, 我们从 2 ∼ n 2\sim n 2 ∼ n 枚举每一个数 i i i , 若 i i i 是素数, 则加入素数表中, 然后我们再从小到大枚举前面的素数 p r i m e [ j ] prime[j] p r i m e [ j ] , 筛掉 i ⋅ p r i m e [ j ] i\cdot prime[j] i ⋅ p r i m e [ j ] , 当 p r i m e [ j ] prime[j] p r i m e [ j ] 是 i i i 的一个素因数时, 那么后面再继续枚举到的素数一定不是所筛的数的最小素因数, 毕竟后面的素数一定大于当前的 p r i m e [ j ] prime[j] p r i m e [ j ] , 所以这时可以终止筛选.
时间复杂度: O ( n ) \mathcal{O}(n) O ( n )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int prime[N];bool isprime[N];void Euler (int n) { memset (isprime, 1 , sizeof isprime); isprime[0 ] = isprime[1 ] = 0 ; for (int i = 2 ; i <= n; ++i) { if (isprime[i]) prime[++prime[0 ]] = i; for (int j = 1 ; j <= prime[0 ] && prime[j] * i <= n; ++j) { isprime[i * prime[j]] = 0 ; if (i % prime[j] == 0 ) break ; } } }
约数
整数惟一分解定理的推论
N = p 1 r 1 p 2 r 2 ⋯ p k r k N=p_1^{r_1}p_2^{r_2}\cdots p_k^{r_k}
N = p 1 r 1 p 2 r 2 ⋯ p k r k
N N N 的正约数的个数为 ( r 1 + 1 ) ( r 2 + 1 ) ⋯ ( r k + 1 ) = ∏ i = 1 k ( r i + 1 ) (r_1+1)(r_2+1)\cdots(r_k+1)=\prod_{i=1}^k(r_i+1) ( r 1 + 1 ) ( r 2 + 1 ) ⋯ ( r k + 1 ) = ∏ i = 1 k ( r i + 1 )
N N N 的约数个数上界为 N \sqrt{N} N
N N N 的所有正约数的和为 ( 1 + p 1 + p 1 2 + ⋯ + p 1 r 1 ) ⋯ ( 1 + p k + ⋯ + p k r k ) = ∏ i = 1 k ( ∑ j = 0 r i p i j ) (1+p_1+p_1^2+\cdots+p_1^{r_1})\cdots(1+p_k+\cdots+p_k^{r_k})=\prod_{i=1}^k(\sum_{j=0}^{r_i}p_i^j) ( 1 + p 1 + p 1 2 + ⋯ + p 1 r 1 ) ⋯ ( 1 + p k + ⋯ + p k r k ) = ∏ i = 1 k ( ∑ j = 0 r i p i j )
时间复杂度: O ( N ) \mathcal{O}(\sqrt{N}) O ( N )
例题
「Luoggu P1463」反素数
这道题只需要知道 1 ∼ 2 ⋅ 1 0 9 1\sim 2\cdot 10^9 1 ∼ 2 ⋅ 1 0 9 内前 12 个素数的积就已经超出 N N N 的范围, 所以打个表然后直接爆搜即可.
(亏我想了半天要怎么转化, 完全没考虑只有 12 个素数会被用到)
最大公约数
左转 gcd & lcm 复习笔记
高精度 gcd ( a , b ) \gcd{(a, b)} g cd( a , b )
更相减损术适用于大整数下求 gcd ( a , b ) \gcd(a, b) g cd( a , b )
a < b a<b a < b 时, gcd ( a , b ) = gcd ( b , a ) \gcd(a, b)=\gcd(b, a) g cd( a , b ) = g cd( b , a )
a = b a=b a = b 时, gcd ( a , b ) = a \gcd(a, b)=a g cd( a , b ) = a
a , b a, b a , b 同为偶数时, gcd ( a , b ) = 2 gcd ( a 2 , b 2 ) \gcd(a, b)=2\gcd(\frac{a}{2}, \frac{b}{2}) g cd( a , b ) = 2 g cd( 2 a , 2 b )
a a a 为偶数, b b b 为奇数时, gcd ( a , b ) = gcd ( a 2 , b ) \gcd(a, b)=\gcd(\frac{a}{2}, b) g cd( a , b ) = g cd( 2 a , b )
a a a 为奇数, b b b 为偶数时, gcd ( a , b ) = gcd ( a , b 2 ) \gcd(a, b)=\gcd(a, \frac{b}{2}) g cd( a , b ) = g cd( a , 2 b )
a , b a, b a , b 同为奇数时, gcd ( a , b ) = gcd ( b , a − b ) \gcd(a, b)=\gcd(b, a-b) g cd( a , b ) = g cd( b , a − b )
容斥原理
原理很简单, 记住一个公式即可
∣ ∩ A i ∣ = ∑ 1 ≤ i ≤ m ∣ A i ∣ − ∑ 1 ≤ i < j ≤ m ∣ A i ∩ A j ∣ + ∑ 1 ≤ i < j < k ≤ m ∣ A i ∩ A j ∩ A k ∣ − ⋯ + ( − 1 ) m + 1 ∑ ∣ A 1 ∩ A 2 ∩ ⋯ ∩ A m ∣ |\cap A_i|=\sum_{1\le i\le m}|A_i|-\sum_{1\le i< j\le m}|A_i\cap A_j|+\sum_{1\le i<j<k\le m}|A_i\cap A_j\cap A_k|-\cdots+(-1)^{m+1}\sum|A_1\cap A_2\cap\cdots\cap A_m|
∣ ∩ A i ∣ = 1 ≤ i ≤ m ∑ ∣ A i ∣ − 1 ≤ i < j ≤ m ∑ ∣ A i ∩ A j ∣ + 1 ≤ i < j < k ≤ m ∑ ∣ A i ∩ A j ∩ A k ∣ − ⋯ + ( − 1 ) m + 1 ∑ ∣ A 1 ∩ A 2 ∩ ⋯ ∩ A m ∣
错排问题
利用容斥原理求解
令集合 S S S 表示 1 , 2 , ⋯ , n 1,2, \cdots, n 1 , 2 , ⋯ , n 的全排列, 则 ∣ S ∣ = n ! |S|=n! ∣ S ∣ = n !
设子集 S i S_i S i 表示 i i i 排在第 i i i 位的排列, 则 ∣ S i ∣ = ( n − 1 ) ! |S_i|=(n-1)! ∣ S i ∣ = ( n − 1 ) !
同理, 设 S i 1 ∩ S i 2 ∩ ⋯ ∩ S i k S_{i_1}\cap S_{i_2}\cap\cdots\cap S_{i_k} S i 1 ∩ S i 2 ∩ ⋯ ∩ S i k 表示 i 1 , i 2 , ⋯ , i k i_1, i_2, \cdots, i_k i 1 , i 2 , ⋯ , i k 这 k k k 个数排在相应位置的排列数, 则 ∣ S i 1 ∩ S i 2 ∩ ⋯ ∩ S i k ∣ = ( n − k ) ! |S_{i_1}\cap S_{i_2}\cap\cdots\cap S_{i_k}|=(n-k)! ∣ S i 1 ∩ S i 2 ∩ ⋯ ∩ S i k ∣ = ( n − k ) !
每个元素都不排在自己位置的排列数为 D n = ∣ S 1 ‾ ∩ S 2 ‾ ∩ ⋯ ∩ S n ‾ ∣ = ∣ S ∣ − ∣ S 1 ∪ S 2 ∪ ⋯ ∪ S n ∣ D_n=|\overline{S_1}\cap\overline{S_2}\cap\cdots\cap\overline{S_n}|=|S|-|S_1\cup S_2\cup\cdots\cup S_n| D n = ∣ S 1 ∩ S 2 ∩ ⋯ ∩ S n ∣ = ∣ S ∣ − ∣ S 1 ∪ S 2 ∪ ⋯ ∪ S n ∣
由容斥原理可得
D n = n ! ( 1 − 1 1 ! + 1 2 ! − 1 3 ! + ⋯ ± 1 n ! ) D_n=n!(1-\frac{1}{1!}+\frac{1}{2!}-\frac{1}{3!}+\cdots\pm\frac{1}{n!})
D n = n ! ( 1 − 1 ! 1 + 2 ! 1 − 3 ! 1 + ⋯ ± n ! 1 )
递推公式
推导过程并不难想, 懒得写了, 直接上公式
D n = ( n − 1 ) ( D n − 1 + D n − 2 ) D_n=(n-1)(D_{n-1}+D_{n-2})
D n = ( n − 1 ) ( D n − 1 + D n − 2 )
欧拉函数
若 gcd ( a , b ) = 1 \gcd{(a, b)}=1 g cd( a , b ) = 1 , 则称 a , b a, b a , b 互质(互素), 记作 a ⊥ b a\bot b a ⊥ b
欧拉函数 φ ( n ) \varphi(n) φ ( n ) 定义为 [ 1 , n ] [1, n] [ 1 , n ] 中与 n n n 互质的数的个数.
若 n n n 为素数, 则 φ ( n ) = n − 1 \varphi(n)=n-1 φ ( n ) = n − 1
容斥原理求欧拉函数
根据整数惟一分解定理, 将 N N N 分解为
N = p 1 r 1 p 2 r 2 ⋯ p k r k N=p_1^{r_1}p_2^{r_2}\cdots p_k^{r_k}
N = p 1 r 1 p 2 r 2 ⋯ p k r k
设 [ 1 , n ] [1, n] [ 1 , n ] 中 p i p_i p i 的倍数的集合为 A i A_i A i , 则 ∣ A i ∣ = ⌊ N p i ⌋ |A_i|=\lfloor \frac{N}{p_i}\rfloor ∣ A i ∣ = ⌊ p i N ⌋
对于 p i ≠ p j p_i\not=p_j p i = p j , 有 ∣ A i ∩ A j ∣ = ⌊ N p i p j ⌋ |A_i\cap A_j|=\lfloor\frac{N}{p_ip_j}\rfloor ∣ A i ∩ A j ∣ = ⌊ p i p j N ⌋
根据容斥原理,
φ ( N ) = ∣ A ∣ − ∣ A 1 ‾ ∪ A 2 ‾ ∪ ⋯ ∪ A k ‾ ∣ = N − ( N p 1 + N p 2 + ⋯ + N p k ) + ( N p 1 p 2 + ⋯ + N p 1 p k ) − ⋯ ± N p 1 p 2 ⋯ p k = N ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) ⋯ ( 1 − 1 p k ) \begin{aligned}\varphi(N)&=|A|-|\overline{A_1}\cup\overline{A_2}\cup\cdots\cup\overline{A_k}| \\\ &=N-(\frac{N}{p_1}+\frac{N}{p_2}+\cdots+\frac{N}{p_k})+(\frac{N}{p_1p_2}+\cdots+\frac{N}{p_1p_k})-\cdots\pm\frac{N}{p_1p_2\cdots p_k} \\\ &=N(1-\frac{1}{p_1})(1-\frac{1}{p_2})\cdots(1-\frac{1}{p_k})\end{aligned}
φ ( N ) = ∣ A ∣ − ∣ A 1 ∪ A 2 ∪ ⋯ ∪ A k ∣ = N − ( p 1 N + p 2 N + ⋯ + p k N ) + ( p 1 p 2 N + ⋯ + p 1 p k N ) − ⋯ ± p 1 p 2 ⋯ p k N = N ( 1 − p 1 1 ) ( 1 − p 2 1 ) ⋯ ( 1 − p k 1 )
素因数分解求欧拉函数的算法
时间复杂度: O ( n ) \mathcal{O}(\sqrt{n}) O ( n )
1 2 3 4 5 6 7 8 9 10 int euler_phi (int n) { int ret = n; for (int i = 2 ; i * i <= n; ++i) if (n % i == 0 ) { ret = ret / i * (i - 1 ); while (n % i == 0 ) n /= i; } if (n > 1 ) ret = ret / n * (n - 1 ); return ret; }
埃氏筛法预处理欧拉函数值
时间复杂度: O ( n log log n ) \mathcal{O}(n\log{\log{n}}) O ( n log log n )
1 2 3 4 5 6 7 8 9 10 11 int phi[N];void euler_phi (int n) { for (int i = 2 ; i <= n; ++i) phi[i] = i; for (int i = 2 ; i * i <= n; ++i) if (phi[i] == i) { phi[i] = i - 1 ; for (int j = i; j <= n; j += i) phi[j] = phi[j] / i * (i - 1 ); } }
欧拉函数的性质
若 a ⊥ b a\bot b a ⊥ b , 则 φ ( a ) φ ( b ) = φ ( a b ) \varphi(a)\varphi(b)=\varphi(ab) φ ( a ) φ ( b ) = φ ( a b ) , 即欧拉函数具有积性函数的性质.
上式分别将 a , b a, b a , b 用整数惟一分解定理表示, 然后带入欧拉函数计算式即可得到证明.
例题
「POJ 3090」Visible Lattice Points
设某点坐标为 ( x 0 , y 0 ) (x_0, y_0) ( x 0 , y 0 ) , 若该点能被看见, 则这个点一定是直线 y = y 0 x 0 x y=\frac{y_0}{x_0}x y = x 0 y 0 x 上距离原点最近的一个整数点.
我们设一点 ( x 1 , y 1 ) (x_1, y_1) ( x 1 , y 1 ) 满足 y 1 x 1 = y 0 x 0 , x 1 > x 0 \frac{y_1}{x_1}=\frac{y_0}{x_0}, x_1>x_0 x 1 y 1 = x 0 y 0 , x 1 > x 0 , 则该点显然不可见, 从这个式子中我们可以知道, x 1 , y 1 x_1, y_1 x 1 , y 1 必然存在一个公约数, 而 x 0 , y 0 x_0, y_0 x 0 , y 0 不存在公约数, 即 x 0 , y 0 x_0, y_0 x 0 , y 0 互质, 因此可见点就是图中所有满足 x 0 , y 0 x_0, y_0 x 0 , y 0 互质的点再加上 ( 1 , 0 ) , ( 0 , 1 ) , ( 1 , 1 ) (1, 0), (0, 1), (1, 1) ( 1 , 0 ) , ( 0 , 1 ) , ( 1 , 1 ) .
固定 y = y 0 y=y_0 y = y 0 , 当 x < y 0 x<y_0 x < y 0 时, 满足条件的点的数量就是 φ ( y 0 ) \varphi(y_0) φ ( y 0 ) , 当 x > y 0 x>y_0 x > y 0 时, 将点 ( x , y 0 ) (x, y_0) ( x , y 0 ) 以 y = x y=x y = x 对称过去得到的点就是固定 x = x i x=x_i x = x i 时 y < x i y<x_i y < x i 的情况, 根据坐标轴关于 y = x y=x y = x 对称的性质, x < y 0 x<y_0 x < y 0 和 x > y 0 x>y_0 x > y 0 两种情况下的答案数相等, 所以我们只需考虑 x < y 0 x<y_0 x < y 0 的情况, 然后乘 2 即可.
最终的答案为: 3 + 2 ⋅ ∑ i = 2 N φ ( i ) 3+2\cdot\sum_{i=2}^N \varphi(i) 3 + 2 ⋅ ∑ i = 2 N φ ( i )
「Luogu P2303」Longge 的问题
考虑满足 gcd ( i , n ) = d \gcd(i, n)=d g cd( i , n ) = d 的 i i i 的个数.
由 gcd ( i , n ) = d \gcd(i, n)=d g cd( i , n ) = d 可以推出 gcd ( i d , n d ) = 1 \gcd(\frac{i}{d}, \frac{n}{d})=1 g cd( d i , d n ) = 1 , 即 i d , n d \frac{i}{d}, \frac{n}{d} d i , d n 互质, 又 i d < n d \frac{i}{d}<\frac{n}{d} d i < d n , 所以这样的 i d \frac{i}{d} d i 的个数为 φ ( n d ) \varphi(\frac{n}{d}) φ ( d n ) , 也就是 i i i 的个数为 φ ( n d ) \varphi(\frac{n}{d}) φ ( d n )
所以答案为 ∑ d ∣ n d φ ( n d ) \sum_{d|n}d\varphi(\frac{n}{d}) ∑ d ∣ n d φ ( d n )
同余
剩余系
剩余系 指模正整数 n n n 的余数所组成的集合.
完全剩余系 : 如果一个剩余系中包含了这个正整数 n n n 所有可能的余数 (0 , 1 , ⋯ , n − 1 0, 1, \cdots, n-1 0 , 1 , ⋯ , n − 1 ) , 那么就称它为模 n n n 的一个完全剩余系, 记作 Z n Z_n Z n .
简化剩余系 :完全剩余系中与 n n n 互质的数的集合, 记作 Z n ∗ Z_n^* Z n ∗ .
同余等价类 : Z n Z_n Z n 里的每一个元素代表所有模 n n n 意义下与它同余的整数, 我们把满足同余关系的所有整数看作一个同余等价类.
在 Z n Z_n Z n 中的四则运算结果全部都要在模 n n n 意义下.
模运算
如果 a ≡ b ( m o d m ) a\equiv b\pmod{m} a ≡ b ( m o d m ) 且有 c ≡ d ( m o d m ) c\equiv d\pmod{m} c ≡ d ( m o d m ) , 那么:
a + c ≡ b + d ( m o d m ) a+c\equiv b+d\pmod{m}
a + c ≡ b + d ( m o d m )
a − c ≡ b − d ( m o d m ) a-c\equiv b-d\pmod{m}
a − c ≡ b − d ( m o d m )
a × c ≡ b × d ( m o d m ) a\times c\equiv b\times d\pmod{m}
a × c ≡ b × d ( m o d m )
( a + b ) m o d m = ( ( a m o d m ) + ( b m o d m ) ) m o d m (a+b)\bmod m=((a\bmod m)+(b\bmod m))\bmod m
( a + b ) m o d m = ( ( a m o d m ) + ( b m o d m ) ) m o d m
( a − b ) m o d m = ( ( a m o d m ) − ( b m o d m ) + m ) m o d m (a-b)\bmod m=((a\bmod m)-(b\bmod m)+m)\bmod m
( a − b ) m o d m = ( ( a m o d m ) − ( b m o d m ) + m ) m o d m
( a × b ) m o d m = ( ( a m o d m ) × ( b m o d m ) ) m o d m (a\times b)\bmod m=((a\bmod m)\times(b\bmod m))\bmod m
( a × b ) m o d m = ( ( a m o d m ) × ( b m o d m ) ) m o d m
快速幂
右转 快速幂复习笔记
费马小定理
若 p p p 为素数, 且 a ⊥ p a\bot p a ⊥ p , 则 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod{p} a p − 1 ≡ 1 ( m o d p ) .
因为 p p p 为素数, 则 2 , 3 , ⋯ , p − 1 2, 3, \cdots, p-1 2 , 3 , ⋯ , p − 1 与 p p p 互质, 且不存在两个数模 p p p 同余.
又 a ⊥ p a\bot p a ⊥ p , 所以 a , 2 a , 3 a , ⋯ , ( p − 1 ) a a, 2a, 3a, \cdots, (p-1)a a , 2 a , 3 a , ⋯ , ( p − 1 ) a 与 p p p 互质, 且不存在两个数模 p p p 同余.
因此 a ⋅ 2 a ⋅ 3 a ⋯ ( p − 1 ) a = ( p − 1 ) ! a p − 1 a\cdot 2a\cdot 3a\cdots(p-1)a=(p-1)!a^{p-1} a ⋅ 2 a ⋅ 3 a ⋯ ( p − 1 ) a = ( p − 1 ) ! a p − 1 与 p p p 互质, 且 ( p − 1 ) ! a p − 1 ≡ ( p − 1 ) ! ( m o d p ) (p-1)!a^{p-1}\equiv (p-1)!\pmod{p} ( p − 1 ) ! a p − 1 ≡ ( p − 1 ) ! ( m o d p )
两边同时除以 ( p − 1 ) ! (p-1)! ( p − 1 ) ! 得到 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod{p} a p − 1 ≡ 1 ( m o d p )
费马小定理的另一种形式: 若 p p p 为素数, 则对任意正整数 a a a 有 a p ≡ a ( m o d p ) a^p\equiv a\pmod{p} a p ≡ a ( m o d p ) .
应用: p p p 是素数, a , p a, p a , p 互质, 则 a b m o d p = a b m o d ( p − 1 ) m o d p a^b\bmod{p}= a^{b\bmod (p-1)}\bmod{p} a b m o d p = a b m o d ( p − 1 ) m o d p .
费马小定理判断素数
多次选取 a a a 来判断 p p p 是否满足费马小定理, 正确的概率随 a a a 选取的次数的增加而增加.
时间复杂度: 设选取 k k k 次 a a a , 每次用快速幂处理的时间为 O ( log p ) \mathcal{O}(\log{p}) O ( log p ) , 则总时间复杂度为 O ( k log p ) \mathcal{O}(k\log{p}) O ( k log p ) .
由于存在 Carmichael 数, 因此上述算法存在缺陷, 即存在合数满足费马小定理.
1 0 4 10^4 1 0 4 以内的 Carmichael 数有: 561, 1105, 1729, 2465, 2821, 6601, 8911.
欧拉定理
(在 p p p 不是素数的情况下, 可以使用欧拉定理)
对于和 m m m 互素的 a a a , 有: a φ ( m ) ≡ 1 ( m o d m ) a^{\varphi(m)}\equiv1\pmod{m} a φ ( m ) ≡ 1 ( m o d m ) .
证明方法和费马小定理差不多.
引理: 若 a , m a, m a , m 互质, 满足 a x ≡ 1 ( m o d m ) a^x\equiv 1\pmod{m} a x ≡ 1 ( m o d m ) 的最小正整数 x 0 x_0 x 0 是 φ ( m ) \varphi(m) φ ( m ) 的约数.
欧拉定理的推论
a , m ( m > 1 ) a, m(m>1) a , m ( m > 1 ) 互素, 则有 a b m o d m = a b m o d φ ( m ) m o d m a^b\bmod{m}=a^{b\bmod\varphi(m)}\bmod m a b m o d m = a b m o d φ ( m ) m o d m .
例题
「POJ 3696」The Luckiest number
设 n n n 个 8 连在一起的正整数为 A n A_n A n , 则 A n = 10 A n − 1 + 8 A_n=10A_{n-1}+8 A n = 1 0 A n − 1 + 8 , 容易求得 A n = 8 9 ( 1 0 n − 1 ) A_n=\frac{8}{9}(10^n-1) A n = 9 8 ( 1 0 n − 1 ) .
若 L ∣ A n L|A_n L ∣ A n , 即 L ∣ 8 9 ( 1 0 n − 1 ) L|\frac{8}{9}(10^n-1) L ∣ 9 8 ( 1 0 n − 1 ) , 可以得到 9 L ∣ 8 ( 1 0 n − 1 ) 9L|8(10^n-1) 9 L ∣ 8 ( 1 0 n − 1 ) , 令 d = gcd ( 9 L , 8 ) d=\gcd(9L, 8) d = g cd( 9 L , 8 ) , 则有 9 L d ∣ ( 1 0 n − 1 ) \frac{9L}{d}|(10^n-1) d 9 L ∣ ( 1 0 n − 1 )
于是 1 0 n ≡ 1 ( m o d 9 L d ) 10^n\equiv 1\pmod{\frac{9L}{d}} 1 0 n ≡ 1 ( m o d d 9 L )
根据欧拉定理的引理, 只需求出 φ ( 9 L d ) \varphi(\frac{9L}{d}) φ ( d 9 L ) , 然后枚举它的约数, 一一验证后取最小的一个数即可.
时间复杂度: O ( L log L ) \mathcal{O}(\sqrt{L}\log{L}) O ( L log L )
扩展欧几里得算法
裴蜀定理 ( Bézout 定理 )
对任何整数 a , b a, b a , b , 关于未知数 x , y x, y x , y 的线性不定方程 ( 称为裴蜀等式 ) a x + b y = c ax+by=c a x + b y = c 有整数解当且仅当 c c c 为 gcd ( a , b ) \gcd{(a, b)} g cd( a , b ) 的倍数.
裴蜀等式有解时必有无穷多个解.
推论: a , b a, b a , b 互素等价于 a x + b y = 1 ax+by=1 a x + b y = 1 有整数解.
例题
「BZOJ 1441」Min
假设 S S S 已知, 于是有方程 A 1 x 1 + A 2 x 2 + ⋯ + A n x n = S A_1x_1+A_2x_2+\cdots+A_nx_n=S A 1 x 1 + A 2 x 2 + ⋯ + A n x n = S
根据裴蜀定理, S S S 必然是 gcd ( A 1 , A 2 , ⋯ , A n ) \gcd{(A_1, A_2, \cdots, A_n)} g cd( A 1 , A 2 , ⋯ , A n ) 的倍数, 取 S m i n = gcd ( A 1 , A 2 , ⋯ , A n ) S_{min}=\gcd{(A_1, A_2, \cdots, A_n)} S m i n = g cd( A 1 , A 2 , ⋯ , A n ) 即可.
扩展欧几里得算法
见 gcd & lcm 复习笔记
根据裴蜀定理, a x + b y = gcd ( a , b ) ax+by=\gcd{(a, b)} a x + b y = g cd( a , b ) 有无穷组解, 而扩展欧几里得算法求出来的只是其中一组特解 ( x 0 , y 0 ) (x_0, y_0) ( x 0 , y 0 ) .
下面考虑求 a x + b y = c ax+by=c a x + b y = c 的一般解.
首先设 c = t gcd ( a , b ) c=t\gcd(a, b) c = t g cd( a , b ) ( t t t 为整数 ) , 则使用扩展欧几里得算法求出 a x + b y = gcd ( a , b ) ax+by=\gcd{(a, b)} a x + b y = g cd( a , b ) 的特解 ( x 0 , y 0 ) (x_0, y_0) ( x 0 , y 0 ) 后, 容易得到 a x + b y = c ax+by=c a x + b y = c 特解为 ( t x 0 , t y 0 ) (tx_0, ty_0) ( t x 0 , t y 0 ) .
由于之后考虑的是 a x + b y = c ax+by=c a x + b y = c , 所以后面用 ( x 0 , y 0 ) (x_0, y_0) ( x 0 , y 0 ) 代替 ( t x 0 , t y 0 ) (tx_0, ty_0) ( t x 0 , t y 0 ) .
将方程的所有解按照 x x x 的大小排序, 则特解后的下一组解 ( x 1 , y 1 ) (x_1, y_1) ( x 1 , y 1 ) 可以表示为 ( x 0 + d 1 , y 0 + d 2 ) (x_0+d_1, y_0+d_2) ( x 0 + d 1 , y 0 + d 2 ) , 其中 d 1 d_1 d 1 为满足条件的最小正整数.
带入方程后得到 a d 1 + b d 2 = 0 ad_1+bd_2=0 a d 1 + b d 2 = 0 , 变形后有 − d 1 d 2 = b a = b gcd ( a , b ) a gcd ( a , b ) -\dfrac{d_1}{d_2}=\dfrac{b}{a}=\dfrac{\frac{b}{\gcd{(a, b)}}}{\frac{a}{\gcd{(a, b)}}} − d 2 d 1 = a b = g c d ( a , b ) a g c d ( a , b ) b .
因此方程的一般解可以表示为 ( x 0 + k b gcd ( a , b ) , y 0 − k a gcd ( a , b ) ) ( k ∈ Z ) \left(x_0+k\dfrac{b}{\gcd{(a, b)}}, y_0-k\dfrac{a}{\gcd{(a, b)}}\right)(k\in \mathbf{Z}) ( x 0 + k g cd( a , b ) b , y 0 − k g cd( a , b ) a ) ( k ∈ Z ) .
为什么这里要将 b a \dfrac{b}{a} a b 再变形为 b gcd ( a , b ) a gcd ( a , b ) \dfrac{\frac{b}{\gcd{(a, b)}}}{\frac{a}{\gcd{(a, b)}}} g c d ( a , b ) a g c d ( a , b ) b 呢?
因为 b a \frac{b}{a} a b 不是最简分数, 这一步变形是化简 b a \frac{b}{a} a b , 直接用 ( x 0 + k b , y 0 − k a ) (x_0+kb, y_0-ka) ( x 0 + k b , y 0 − k a ) 来表示特解的话会漏掉一些情况, 如 ( x 0 + b gcd ( a , b ) , y 0 − a gcd ( a , b ) ) (x_0+\frac{b}{\gcd{(a, b)}}, y_0-\frac{a}{\gcd{(a, b)}}) ( x 0 + g c d ( a , b ) b , y 0 − g c d ( a , b ) a ) 就不能被 ( x 0 + k b , y 0 − k a ) (x_0+kb, y_0-ka) ( x 0 + k b , y 0 − k a ) 表示.
逆元
模 n n n 意义下乘法的逆
如果在 Z n Z_n Z n 中两元素 a , b a, b a , b 满足 a ⋅ b = 1 a\cdot b=1 a ⋅ b = 1 , 那么我们就说 a , b a, b a , b 互为模 n n n 意义下乘法的逆元, 记作 a = b − 1 , b = a − 1 a=b^{-1}, b=a^{-1} a = b − 1 , b = a − 1 .
逆元
当 a , m a, m a , m 互素的时候, 若 a x ≡ 1 ( m o d m ) ax\equiv 1\pmod{m} a x ≡ 1 ( m o d m ) , 则称 x x x 为 a a a 关于模 m m m 的逆元, 记作 a − 1 a^{-1} a − 1 .
在 [ 0 , m ) [0, m) [ 0 , m ) 的范围内, 逆元是唯一的.
求解逆元
求解逆元等价于解方程 a x + m y = 1 ax+my=1 a x + m y = 1
直接使用扩展欧几里得算法即可.
欧拉定理求逆元
因为 a , m a, m a , m 互素, 根据欧拉定理, 有 a ⋅ a φ ( m ) − 1 ≡ 1 ( m o d m ) a\cdot a^{\varphi(m)-1}\equiv 1\pmod{m} a ⋅ a φ ( m ) − 1 ≡ 1 ( m o d m ) , 因此 a φ ( m ) − 1 a^{\varphi(m)-1} a φ ( m ) − 1 为所求逆元.
线性求逆元: 递推法
递推法求解 1 ∼ n 1\sim n 1 ∼ n 的逆元.
假设当前求解的是 i i i 关于模 p p p 的逆元.
根据带余除法, p = i q + r p=iq+r p = i q + r , 两边分别对 p p p 取模得到 i q + r ≡ 0 ( m o d p ) iq+r\equiv 0\pmod{p} i q + r ≡ 0 ( m o d p )
若 i i i 不为 p p p 的倍数, 则 r r r 不为 0 , 因此 r − 1 r^{-1} r − 1 存在.
在上式两边乘 i − 1 r − 1 i^{-1}r^{-1} i − 1 r − 1 得到 q r − 1 + i − 1 ≡ 0 ( m o d p ) qr^{-1}+i^{-1}\equiv 0\pmod{p} q r − 1 + i − 1 ≡ 0 ( m o d p ) , 即
r − 1 ≡ − q r − 1 = − r − 1 ⌊ p i ⌋ ( m o d p ) r^{-1}\equiv -qr^{-1}=-r^{-1}\left\lfloor \dfrac{p}{i}\right\rfloor\pmod{p}
r − 1 ≡ − q r − 1 = − r − 1 ⌊ i p ⌋ ( m o d p )
为了防止答案为负数, 使用 r − 1 ( p − ⌊ p i ⌋ ) r^{-1}(p-\left\lfloor \frac{p}{i}\right\rfloor) r − 1 ( p − ⌊ i p ⌋ ) 代替 − r − 1 ⌊ p i ⌋ -r^{-1}\left\lfloor \frac{p}{i}\right\rfloor − r − 1 ⌊ i p ⌋ .
时间复杂度: O ( n ) \mathcal{O}(n) O ( n )
1 2 3 inv[1 ] = 1 ; for (int i = 2 ; i <= n; ++i) inv[i] = inv[p % i] * (p - p / i) % p;
线性求逆元: 倒推法
先直接求解 n ! n! n ! 的逆元, 然后利用 ( ( n − 1 ) ! ) − 1 ≡ ( n ! ) − 1 ⋅ n ( m o d p ) ((n-1)!)^{-1}\equiv(n!)^{-1}\cdot n\pmod{p} ( ( n − 1 ) ! ) − 1 ≡ ( n ! ) − 1 ⋅ n ( m o d p ) 倒推求得 1 ! ∼ ( n − 1 ) ! 1!\sim (n-1)! 1 ! ∼ ( n − 1 ) ! 的逆元.
接着再利用 n − 1 ≡ ( n ! ) − 1 ⋅ ( n − 1 ) ! ( m o d p ) n^{-1}\equiv (n!)^{-1}\cdot (n-1)!\pmod{p} n − 1 ≡ ( n ! ) − 1 ⋅ ( n − 1 ) ! ( m o d p ) 求解 1 ∼ n 1\sim n 1 ∼ n 的逆元.
例题
「POJ 1845」Sumdiv
首先利用整数惟一分解定理将 A A A 表示为 A = p 1 r 1 p 2 r 2 ⋯ p n r n A=p_1^{r_1}p_2^{r_2}\cdots p_n^{r_n} A = p 1 r 1 p 2 r 2 ⋯ p n r n .
则 A B A^B A B 约数和为
( 1 + p 1 + p 1 2 + ⋯ + p 1 B ⋅ r 1 ) ( 1 + p 2 + p 2 2 + ⋯ + p 2 B ⋅ r 2 ) ⋯ ( 1 + p n + p n 2 + ⋯ + p n B ⋅ r n ) (1+p_1+p_1^2+\cdots +p_1^{B\cdot r_1})(1+p_2+p_2^2+\cdots+p_2^{B\cdot r_2})\cdots(1+p_n+p_n^2+\cdots+p_n^{B\cdot r_n})
( 1 + p 1 + p 1 2 + ⋯ + p 1 B ⋅ r 1 ) ( 1 + p 2 + p 2 2 + ⋯ + p 2 B ⋅ r 2 ) ⋯ ( 1 + p n + p n 2 + ⋯ + p n B ⋅ r n )
可以发现, 每一个括号里都是一个等比数列求和, 以 p i p_i p i 为例, 它的和可以写成 p i B ⋅ r i + 1 − 1 p i − 1 \dfrac{p_i^{B\cdot r_i+1}-1}{p_i-1} p i − 1 p i B ⋅ r i + 1 − 1 , 然后我们可以利用快速幂求解分子 p i B ⋅ r i + 1 m o d 9901 p_i^{B\cdot r_i+1}\bmod{9901} p i B ⋅ r i + 1 m o d 9 9 0 1 , 这时若 p i − 1 > ( p i B ⋅ r i + 1 − 1 ) m o d 9901 p_i-1>(p_i^{B\cdot r_i+1}-1)\bmod{9901} p i − 1 > ( p i B ⋅ r i + 1 − 1 ) m o d 9 9 0 1 , 我们会得到 0 0 0 , 这显然是错的, 而模数 9901 9901 9 9 0 1 正好为素数, 因此考虑用 p i − 1 p_i-1 p i − 1 的逆元与分子的结果相乘来代替除法.
当 p i − 1 p_i-1 p i − 1 为 9901 9901 9 9 0 1 的倍数时不存在逆元, 这时我们可以发现 p i ≡ 1 ( m o d 9901 ) p_i\equiv 1\pmod{9901} p i ≡ 1 ( m o d 9 9 0 1 ) , 因此 1 , p i , p i 2 , ⋯ , p i B ⋅ r i + 1 ≡ 1 ( m o d 9901 ) 1, p_i, p_i^2, \cdots, p_i^{B\cdot r_i+1}\equiv 1\pmod{9901} 1 , p i , p i 2 , ⋯ , p i B ⋅ r i + 1 ≡ 1 ( m o d 9 9 0 1 ) , 所以 1 + p i + p i 2 + ⋯ + p i B ⋅ r i ≡ B ⋅ r i + 1 ( m o d 9901 ) 1+p_i+p_i^2+\cdots+p_i^{B\cdot r_i}\equiv B\cdot r_i+1\pmod{9901} 1 + p i + p i 2 + ⋯ + p i B ⋅ r i ≡ B ⋅ r i + 1 ( m o d 9 9 0 1 ) .
线性同余方程
形如 a x ≡ c ( m o d m ) ax\equiv c\pmod{m} a x ≡ c ( m o d m ) 的方程,称为线性同余方程。
朴素算法
将 x = 1 , 2 , ⋯ , m − 1 x=1, 2, \cdots, m-1 x = 1 , 2 , ⋯ , m − 1 一次带进去验证即可,这个朴素算法的复杂度取决于 m m m 。
扩展欧几里得算法
可以将方程看作 a x + m y = c ax+my=c a x + m y = c ,然后利用扩展欧几里得方法求解。
根据裴蜀定理,当且仅当 gcd ( a , m ) ∣ c \gcd{(a, m)}|c g cd( a , m ) ∣ c 时方程有解。
令 d = gcd ( a , m ) d=\gcd(a, m) d = g cd( a , m ) ,则方程一共有 d d d 个解,我们用扩展欧几里得算法求得特解 x 0 x_0 x 0 ,则方程的通解 x i = x 0 + i ⋅ m d ( i = 0 , 1 , ⋯ , d − 1 ) x_i=x_0+i\cdot \dfrac{m}{d}(i=0, 1, \cdots, d-1) x i = x 0 + i ⋅ d m ( i = 0 , 1 , ⋯ , d − 1 ) 。
欧拉定理
令 d = gcd ( a , m ) d=\gcd{(a, m)} d = g cd( a , m ) ,若 d ∤ c d \nmid c d ∤ c 则方程无解。
然后令 a ′ = a d , c ′ = c d , m ′ = m d a'=\dfrac{a}{d}, c'=\dfrac{c}{d}, m'=\dfrac{m}{d} a ′ = d a , c ′ = d c , m ′ = d m ,则 gcd ( a ′ , m ′ ) = 1 \gcd{(a', m')}=1 g cd( a ′ , m ′ ) = 1 ,原方程变为 a ′ x ≡ c ′ ( m o d m ′ ) a'x\equiv c'\pmod{m'} a ′ x ≡ c ′ ( m o d m ′ ) ,由欧拉定理,a ′ φ ( m ′ ) ≡ 1 ( m o d m ′ ) a'^{\varphi(m')}\equiv 1\pmod{m'} a ′ φ ( m ′ ) ≡ 1 ( m o d m ′ ) ,在方程两边分别乘上上式,得到 a ′ x ≡ c ′ a ′ φ ( m ′ ) ( m o d m ′ ) a'x\equiv c'a'^{\varphi(m')}\pmod{m'} a ′ x ≡ c ′ a ′ φ ( m ′ ) ( m o d m ′ ) ,即 x ≡ c ′ a ′ φ ( m ′ ) − 1 ( m o d m ′ ) x\equiv c'a'^{\varphi(m')-1}\pmod{m'} x ≡ c ′ a ′ φ ( m ′ ) − 1 ( m o d m ′ ) ,于是我们得到原方程的特解 x 0 = d c ′ a ′ φ ( m ′ ) − 1 x_0=dc'a'^{\varphi(m')-1} x 0 = d c ′ a ′ φ ( m ′ ) − 1 ,因此原方程的解为 x i = x 0 + i ⋅ m ′ ( i = 1 , 2 , ⋯ , d − 1 ) x_i=x_0+i\cdot m'(i=1, 2, \cdots,d-1) x i = x 0 + i ⋅ m ′ ( i = 1 , 2 , ⋯ , d − 1 ) 。
例题
线性组合
对应整数数列 A 1 , A 2 , ⋯ , A n A_1, A_2, \cdots, A_n A 1 , A 2 , ⋯ , A n 是否存在 X 1 , X 2 , ⋯ , X n X_1, X_2, \cdots, X_n X 1 , X 2 , ⋯ , X n , 使得 A 1 X 1 + A 2 X 2 + ⋯ + A n X n = C A_1X_1+A_2X_2+\cdots+A_nX_n=C A 1 X 1 + A 2 X 2 + ⋯ + A n X n = C ,其中 gcd ( A 1 , A 2 , ⋯ , A n ) ∣ C ( n ≥ 2 ) \gcd{(A_1, A_2, \cdots, A_n)}\mid C(n\ge2) g cd( A 1 , A 2 , ⋯ , A n ) ∣ C ( n ≥ 2 ) 。如有,请找出一组整数解 ( x 1 , x 2 , x 3 , x 4 ) (x_1, x_2, x_3, x_4) ( x 1 , x 2 , x 3 , x 4 ) 满足 12 x 1 + 24 x 2 + 18 x 3 + 15 x 4 = 3 12x_1+24x_2+18x_3+15x_4=3 1 2 x 1 + 2 4 x 2 + 1 8 x 3 + 1 5 x 4 = 3 .
题中的方程是 n 元形式的扩展欧几里得方程,我们尝试将 n 元逐步降为二元得到最终解。
设 d = gcd ( A 1 , A 2 , ⋯ , A n ) d=\gcd{(A_1, A_2, \cdots, A_n)} d = g cd( A 1 , A 2 , ⋯ , A n ) ,令 C ′ = C d , A i ′ = A i d ( i = 1 , 2 , ⋯ , n ) C'=\dfrac{C}{d},A_i'=\dfrac{A_i}{d}(i=1, 2, \cdots, n) C ′ = d C , A i ′ = d A i ( i = 1 , 2 , ⋯ , n ) ,首先将方程变形为 A 1 ′ X 1 + A 2 ′ X 2 + ⋯ + A n ′ X n = C ′ A_1'X_1+A_2'X_2+\cdots+A_n'X_n=C' A 1 ′ X 1 + A 2 ′ X 2 + ⋯ + A n ′ X n = C ′ ,此时满足 gcd ( A 1 ′ , A 2 ′ , ⋯ , A n ′ , C ′ ) = 1 \gcd{(A_1', A_2', \cdots, A_n', C')}=1 g cd( A 1 ′ , A 2 ′ , ⋯ , A n ′ , C ′ ) = 1 。
然后我们考虑求解方程 A 1 ′ X 1 + gcd ( A 2 ′ , A 3 ′ , ⋯ , A n ′ ) Y 1 = C ′ A_1'X_1+\gcd(A_2', A_3', \cdots, A_n')Y_1=C' A 1 ′ X 1 + g cd( A 2 ′ , A 3 ′ , ⋯ , A n ′ ) Y 1 = C ′ ,利用扩展欧几里得方法求得特解 X 1 , Y 1 X_1,Y_1 X 1 , Y 1 ,由于题中仅要求得到一组解,因此我们只取特解即可,然后再以同样的方法求解 A 2 ′ X 2 + A 3 ′ X 3 + ⋯ + A n ′ X n = gcd ( A 2 ′ , A 3 ′ , ⋯ , A n ′ ) Y 1 A_2'X_2+A_3'X_3+\cdots+A_n'X_n=\gcd(A_2', A_3', \cdots, A_n')Y_1 A 2 ′ X 2 + A 3 ′ X 3 + ⋯ + A n ′ X n = g cd( A 2 ′ , A 3 ′ , ⋯ , A n ′ ) Y 1 便可以实现逐渐降元了。
线性同余方程组(模互素)
考虑形如 x ≡ a i ( m o d m i ) x\equiv a_i\pmod{m_i} x ≡ a i ( m o d m i ) 的若干个线性同余方程联合得到的方程组,例如
{ x ≡ 2 ( m o d 3 ) x ≡ 3 ( m o d 5 ) x ≡ 5 ( m o d 7 ) \begin{cases}
x &\equiv& 2\pmod{3} \\
x &\equiv& 3\pmod{5} \\
x &\equiv& 5\pmod{7}
\end{cases}
⎩ ⎪ ⎪ ⎨ ⎪ ⎪ ⎧ x x x ≡ ≡ ≡ 2 ( m o d 3 ) 3 ( m o d 5 ) 5 ( m o d 7 )
一种可行的解法是令 x = 3 y + 2 x=3y+2 x = 3 y + 2 ,然后将方程 ( 2 ) (2) ( 2 ) 改写成 y ≡ 2 ( m o d 5 ) y\equiv 2\pmod{5} y ≡ 2 ( m o d 5 ) ,接着再令 y = 5 z + 2 y=5z+2 y = 5 z + 2 代入方程 ( 3 ) (3) ( 3 ) 得到 z ≡ 4 ( m o d 7 ) z\equiv 4\pmod{7} z ≡ 4 ( m o d 7 ) ,再令 z = 7 k + 4 z=7k+4 z = 7 k + 4 ,最后我们可以得到解 x ≡ 68 ( m o d 105 ) x\equiv68\pmod{105} x ≡ 6 8 ( m o d 1 0 5 ) 。
中国剩余定理
若线性同余方程组 x ≡ a i ( m o d m i ) ( i = 1 , ⋯ , n ) x\equiv a_i\pmod{m_i}(i=1, \cdots, n) x ≡ a i ( m o d m i ) ( i = 1 , ⋯ , n ) 的模数 m i m_i m i 两两互素,则 x x x 在 m o d M ( M = ∏ i = 1 n m i ) \bmod{M}(M=\prod_{i=1}^n m_i) m o d M ( M = ∏ i = 1 n m i ) 下有唯一解。
令 M i = M m i M_i=\dfrac{M}{m_i} M i = m i M ,有 gcd ( M i , m i ) = 1 \gcd{(M_i, m_i)}=1 g cd( M i , m i ) = 1 ,因此 M i M_i M i 在 m o d m i \bmod{m_i} m o d m i 下的逆元存在,设其为 t i t_i t i ,于是有 a i M i t i ≡ a i ( m o d m i ) , a i M i t i ≡ 0 ( m o d m j ) ( j ≠ i ) a_iM_it_i\equiv a_i\pmod{m_i},a_iM_it_i\equiv0\pmod{m_j}(j\not= i) a i M i t i ≡ a i ( m o d m i ) , a i M i t i ≡ 0 ( m o d m j ) ( j = i ) 。
可以得到解 x ≡ ∑ i = 1 n a i M i t i ( m o d M ) x\equiv\sum_{i=1}^na_iM_it_i\pmod{M} x ≡ ∑ i = 1 n a i M i t i ( m o d M ) 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int CRT (const int a[], const int m[], int n) { int M = 1 , ret = 0 ; for (int i = 1 ; i <= n; ++i) M *= m[i]; for (int i = 1 ; i <= n; ++i) { int ti = getinv (m[i], a[i]), Mi = M / m[i]; ret = (ret + a[i] * ti * Mi % M) % M; } return ret; } int getinv (int a, int b) { int x, y; exgcd (a, b, x, y); return x; }
线性同余方程组(模不互素)
对于模不互素的线性同余方程组
{ x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) ⋯ x ≡ a n ( m o d m n ) \begin{cases}
x &\equiv a_1\pmod{m_1} \\
x &\equiv a_2\pmod{m_2} \\
&\cdots \\
x &\equiv a_n\pmod{m_n}
\end{cases}
⎩ ⎪ ⎪ ⎪ ⎪ ⎨ ⎪ ⎪ ⎪ ⎪ ⎧ x x x ≡ a 1 ( m o d m 1 ) ≡ a 2 ( m o d m 2 ) ⋯ ≡ a n ( m o d m n )
考虑求解方程数量为 2 的情形,当方程数量大于 2 时迭代求解。
{ x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) \begin{cases}
x &\equiv a_1\pmod{m_1} \\
x &\equiv a_2\pmod{m_2}
\end{cases}
{ x x ≡ a 1 ( m o d m 1 ) ≡ a 2 ( m o d m 2 )
设 y = x − a 1 y=x-a_1 y = x − a 1 ,则方程组变为
{ y ≡ 0 ( m o d m 1 ) y ≡ a 2 − a 1 ( m o d m 2 ) \begin{cases}
y &\equiv 0 &\pmod{m_1} \\
y &\equiv a_2-a_1 &\pmod{m_2}
\end{cases}
{ y y ≡ 0 ≡ a 2 − a 1 ( m o d m 1 ) ( m o d m 2 )
设 d = gcd ( m 1 , m 2 ) d=\gcd{(m_1, m_2)} d = g cd( m 1 , m 2 ) ,根据裴蜀定理,若 d ∤ ( a 2 − a 1 ) d \nmid (a_2-a_1) d ∤ ( a 2 − a 1 ) ,则方程组无解,否则令 y ′ = y d , a ′ = a 2 − a 1 d , m i ′ = m 1 d ( i = 1 , 2 ) y'=\dfrac{y}{d},a'=\dfrac{a_2-a_1}{d}, m_i'=\dfrac{m_1}{d}(i=1,2) y ′ = d y , a ′ = d a 2 − a 1 , m i ′ = d m 1 ( i = 1 , 2 ) ,有
{ y ′ ≡ 0 ( m o d m 1 ′ ) y ′ ≡ a ′ ( m o d m 2 ′ ) \begin{cases}
y' &\equiv{0} &\pmod{m_1'} \\
y' &\equiv{a'} &\pmod{m_2'}
\end{cases}
{ y ′ y ′ ≡ 0 ≡ a ′ ( m o d m 1 ′ ) ( m o d m 2 ′ )
此时 gcd ( m 1 ′ , m 2 ′ ) = 1 \gcd{(m_1', m_2')}=1 g cd( m 1 ′ , m 2 ′ ) = 1 ,令 y ′ = k m 1 ′ y'=km_1' y ′ = k m 1 ′ ,再由欧拉定理可得 k ≡ a ′ m 1 ′ φ ( m 2 ′ ) − 1 ( m o d m 2 ′ ) k\equiv{a'm_1'^{\varphi(m_2')-1}}\pmod{m_2'} k ≡ a ′ m 1 ′ φ ( m 2 ′ ) − 1 ( m o d m 2 ′ ) ,于是 y ≡ d a ′ m 1 ′ φ ( m 2 ′ ) ( m o d d m 1 ′ m 2 ′ ) y\equiv{da'm_1'^{\varphi{(m_2')}}}\pmod{dm_1'm_2'} y ≡ d a ′ m 1 ′ φ ( m 2 ′ ) ( m o d d m 1 ′ m 2 ′ ) ,最后代回去可以得到 x ≡ ( a 2 − a 1 ) m 1 ′ φ ( m 2 ′ ) + a 1 ( m o d d m 1 ′ m 2 ′ ) x\equiv{(a_2-a_1)m_1'^{\varphi{(m_2')}}+a_1}\pmod{dm_1'm_2'} x ≡ ( a 2 − a 1 ) m 1 ′ φ ( m 2 ′ ) + a 1 ( m o d d m 1 ′ m 2 ′ ) 。
例题
「POJ 2891」Strange Way to Express Integers
算法和上述一致。
假设我们已经通过迭代求解得到前 k − 1 k-1 k − 1 个方程的一个解 x 0 x_0 x 0 ,令 M = ∏ i = 1 k − 1 m i M=\prod_{i=1}^{k-1}m_i M = ∏ i = 1 k − 1 m i ,则 x = x 0 + i ⋅ M x=x_0+i\cdot M x = x 0 + i ⋅ M 是前 k − 1 k-1 k − 1 个方程的通解。
考虑第 k k k 个方程,我们可以将其改写为 x 0 + t ⋅ M ≡ a k ( m o d m k ) x_0+t\cdot M\equiv{a_k}\pmod{m_k} x 0 + t ⋅ M ≡ a k ( m o d m k ) ,即 t ⋅ M ≡ a k − x 0 ( m o d m k ) t\cdot M\equiv{a_k-x_0}\pmod{m_k} t ⋅ M ≡ a k − x 0 ( m o d m k ) ,接下来找到一个合适的 t t t 即可,也就是求解一个同余方程了,利用欧拉定理求解即可。
高次同余方程
第一类高次同余方程
形如 a x ≡ b ( m o d p ) a^x\equiv{b}\pmod{p} a x ≡ b ( m o d p ) 的方程称为第一类高次同余方程,其中 gcd ( a , p ) = 1 \gcd(a, p)=1 g cd( a , p ) = 1 。
BSGS
解决这一类方程主要采用 BSGS (Baby Step Giant Step) 算法。
将 x x x 写成 x = k t − m ( 0 ≤ m ≤ t − 1 ) x=kt-m(0\le m\le t-1) x = k t − m ( 0 ≤ m ≤ t − 1 ) 的形式,则原方程可变形为 ( a t ) k ≡ b ⋅ a m ( m o d p ) (a^t)^k\equiv{b\cdot a^m\pmod{p}} ( a t ) k ≡ b ⋅ a m ( m o d p ) 。
假设 t t t 已知,那么我们只需枚举 k k k ,然后计算相应的 b ⋅ a m b\cdot a^m b ⋅ a m ,判断是否满足变形后的等式即可。
因为在枚举 k k k 的过程中 m m m 的取值也在变化,但 m m m 的取值范围是不变的,因此我们可以预处理所有可能的 b ⋅ a m b\cdot a^m b ⋅ a m 值,用一个 Hash 表储存。
由欧拉定理可知,有 a φ ( p ) ≡ 1 ( m o d p ) a^{\varphi(p)}\equiv{1}\pmod{p} a φ ( p ) ≡ 1 ( m o d p ) ,而 φ ( p ) < p \varphi(p)<p φ ( p ) < p ,因此从 1~p ,模 p p p 意义下 a a a 的幂至少完成了一次循环,所以最小整数解 x < p x<p x < p ,进而我们可以从 0 0 0 到 p t \dfrac{p}{t} t p 枚举 k k k ,而 m ∈ [ 0 , t − 1 ] m\in[0,t-1] m ∈ [ 0 , t − 1 ] ,因此时间复杂度为 O ( p t + t ) \mathcal{O}(\dfrac{p}{t}+t) O ( t p + t ) ,当 t = p t=\sqrt{p} t = p 时复杂度最小。
时间复杂度:O ( 2 p ) \mathcal{O}(2\sqrt{p}) O ( 2 p )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int BSGS (int a, int b, int p) { b %= p; if (a % p == 0 ) return b ? 1 : -1 ; map <int , int > hash; int t = sqrt (p) + 1 ; for (int i = 0 ; i < t; ++i) { int val = (long long )b * power (a, i, p) % p; hash[val] = i; } a = power (a, t, p); for (int i = 0 ; i <= t; ++i) { int val = power (a, i, p); int j = hash.find (val) == hash.end () ? -1 : hash[val]; if (j >= 0 && i * t - j >= 0 ) return i * t - j; } return -1 ; }
第二类高次同余方程
形如 x k ≡ b ( m o d p ) x^k\equiv{b}\pmod{p} x k ≡ b ( m o d p ) 的方程称为第二类高次同余方程。
首先引入阶 和原根 的概念,这一部分和抽象代数相关,我目前还不会 QAQ 。
阶
满足同余式 a n ≡ 1 ( m o d p ) a^n\equiv{1}\pmod{p} a n ≡ 1 ( m o d p ) 的最小整数 n n n 称为 a a a 模 p p p 的阶,记作 δ p ( a ) \delta_p(a) δ p ( a ) 。
由欧拉定理可知,当 gcd ( a , p ) = 1 \gcd(a, p)=1 g cd( a , p ) = 1 时,有 a φ ( p ) ≡ 1 ( m o d p ) a^{\varphi(p)}\equiv{1}\pmod{p} a φ ( p ) ≡ 1 ( m o d p ) ,因此阶的存在性得证。
性质 1 :a , a 2 , ⋯ , a δ p ( a ) a,a^2,\cdots,a^{\delta_p(a)} a , a 2 , ⋯ , a δ p ( a ) 模 m m m 两两不同余。
性质 2 :若 a n ≡ 1 ( m o d p ) a^n\equiv{1}\pmod{p} a n ≡ 1 ( m o d p ) ,则 n ∣ δ p ( a ) n \mid \delta_p(a) n ∣ δ p ( a ) 。
推论 :若 a m ≡ a n ( m o d p ) a^m\equiv{a^n}\pmod{p} a m ≡ a n ( m o d p ) ,则 m ≡ n ( m o d δ p ( a ) ) m\equiv{n}\pmod{\delta_p(a)} m ≡ n ( m o d δ p ( a ) ) 。
性质 3 :设 p ∈ N ∗ , a , b ∈ Z , gcd ( a , p ) = gcd ( b , p ) = 1 p\in\mathbb{N}^*,\, a,b\in\mathbb{Z},\gcd(a,p)=\gcd(b,p)=1 p ∈ N ∗ , a , b ∈ Z , g cd( a , p ) = g cd( b , p ) = 1 ,则 δ p ( a b ) = δ p ( a ) δ p ( b ) \delta_p(ab)=\delta_p(a)\delta_p(b) δ p ( a b ) = δ p ( a ) δ p ( b ) 的充要条件是 gcd ( δ p ( a ) , δ p ( b ) ) = 1 \gcd(\delta_p(a),\delta_p(b))=1 g cd( δ p ( a ) , δ p ( b ) ) = 1 。
性质 4 :设 k ∈ N , p ∈ N ∗ , a ∈ Z , gcd ( a , p ) = 1 k\in\mathbb{N},p\in\mathbb{N}^*,a\in\mathbb{Z},\gcd(a,p)=1 k ∈ N , p ∈ N ∗ , a ∈ Z , g cd( a , p ) = 1 ,则 δ p ( a k ) = δ p ( a ) gcd ( δ p ( a ) , k ) \delta_p(a^k)=\dfrac{\delta_p(a)}{\gcd(\delta_p(a),k)} δ p ( a k ) = g cd( δ p ( a ) , k ) δ p ( a ) 。
原根
设 p ∈ N ∗ , a ∈ Z p\in\mathbb{N}^*,a\in\mathbb{Z} p ∈ N ∗ , a ∈ Z ,若 gcd ( a , p ) = 1 \gcd(a,p)=1 g cd( a , p ) = 1 ,且 δ p ( a ) = φ ( p ) \delta_p(a)=\varphi(p) δ p ( a ) = φ ( p ) ,则称 a a a 为模 m m m 的原根。
以下基于 p p p 为质数的情况进行讨论。
如何判断 a a a 是否是 p p p 的原根?
由费马小定理,方程 a x ≡ 1 ( m o d p ) a^x\equiv{1}\pmod{p} a x ≡ 1 ( m o d p ) 的一个解为 x = p − 1 x=p-1 x = p − 1 ,因此最小整数解 x m i n ∣ ( p − 1 ) x_{min}\mid (p-1) x m i n ∣ ( p − 1 ) ,而满足 x m i n = p − 1 x_{min}=p-1 x m i n = p − 1 的整数 a a a 是 p p p 的原根,所以我们逐个枚举 p − 1 p-1 p − 1 的约数 k k k ,如果只有当 k = p − 1 k=p-1 k = p − 1 时满足 a k ≡ 1 ( m o d p ) a^k\equiv{1}\pmod{p} a k ≡ 1 ( m o d p ) ,则 a a a 是 p p p 的原根。
下面考虑求解 x k ≡ b ( m o d p ) x^k\equiv{b}\pmod{p} x k ≡ b ( m o d p ) 。
由阶的性质 1 ,存在唯一的正整数 m m m ,满足 a m ≡ b ( m o d p ) , 0 ≤ m ≤ p − 1 a^m\equiv{b}\pmod{p},0\le m\le p-1 a m ≡ b ( m o d p ) , 0 ≤ m ≤ p − 1 ,其中 a a a 是 p p p 的原根,m m m 可以由第一类高次同余方程求出。
同样,存在唯一正整数 y y y ,使得 x ≡ a y ( m o d p ) x\equiv{a^y}\pmod{p} x ≡ a y ( m o d p ) ,于是上述方程变为 a k y ≡ a m ( m o d p ) a^{ky}\equiv{a^m}\pmod{p} a k y ≡ a m ( m o d p ) 。
由阶的性质 2 的推论 ,k y ≡ m ( m o d p − 1 ) ky\equiv{m}\pmod{p-1} k y ≡ m ( m o d p − 1 ) ,于是我们求解这个线性同余方程得到 y y y 便可以得到 x x x 。
Comments