模运算是一个高深的地方,初来乍到,还是写一下为敬QAQ。。。
记号 我们把 a a a 除以 m m m 所得的余数记作 a mod m a \bmod m a modm 。 如果 a mod m = b mod m a \bmod m = b \bmod m a modm = b modm ,即 a a a , b b b 除以 m m m 所得的余数相等,那么我们记作:
a ≡ b ( mod m )
a\equiv b\pmod{m}
a ≡ b ( modm )基本性质 模运算有一些基本性质:如果 a ≡ b ( mod m ) a\equiv b\pmod{m} a ≡ b ( modm ) 且有 c ≡ d ( mod m ) c\equiv d\pmod{m} c ≡ d ( modm ) ,那么下面的模运算律成立:
a + c ≡ b + d ( mod m ) a − c ≡ b − d ( mod m ) a × c ≡ b × d ( mod m )
\begin{aligned}a + c\equiv b + d\pmod{m}\\a - c\equiv b - d\pmod{m}\\a \times c\equiv b \times d\pmod{m}\end{aligned}
a + c ≡ b + d ( modm ) a − c ≡ b − d ( modm ) a × c ≡ b × d ( modm ) 这就是我们平常经常利用的性质,如果答案对一个数取模,那么模了再加,乘,减都是不影响答案的。特别注意除法是没有这个性质的!
剩余系 如果一个剩余系中包含了这个正整数 n n n 所有可能的余数(一般地,对于任意正整数 n n n ,有 n n n 个余数:0 , 1 , 2 , . . . , n − 1 0,1,2,...,n-1 0 , 1 , 2 , . . . , 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 意义下与它同余的整数。例如 n = 5 n = 5 n = 5 时,Z 5 Z_5 Z 5 的元素 3 3 3 实际上代表了 3 , 8 , 1 3 , 1 8 , . . . . , 5 k + 3 ( k ∈ N ) 3, 8, 13, 18,....,5k + 3(k\in N) 3 , 8 , 1 3 , 1 8 , . . . . , 5 k + 3 ( k ∈ N ) 这些模 5 5 5 余 3 3 3 的数。 我们把满足同余关系的所有整数看作一个同余等价类 。 自然地,在 Z n Z_n Z n 中的加法,减法,乘法,结果全部要在模 n n n 意义下面了,例如在 Z 5 Z_5 Z 5 中,3 + 2 = 0 , 3 × 2 = 1 3 + 2 = 0, 3 \times 2 = 1 3 + 2 = 0 , 3 × 2 = 1 。
逆元 在实数运算下面,如果 a b = 1 ab = 1 a b = 1 ,那么可以说 a , b a, b a , b 互为倒数,它们相乘永远得 1 1 1 。不幸的是,mod m \bmod m modm 的运算下面也有倒数的概念,而且要恐怖的多。 如果在 Z n Z_n Z n 中的两元素 a a a , b b b 满足 a b = 1 ab = 1 a b = 1 ,比如在 Z 1 5 Z_{15} Z 1 5 中,7 ∗ 1 3 = 1 7*13 = 1 7 ∗ 1 3 = 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 。 我们知道,除以一个数的等于乘这个数的倒数,在模运算中,除以一个数等于乘上这个数的逆(如果这个数存在乘法逆的话)!举例说明,在 Z 5 Z_5 Z 5 中,4 ÷ 3 = 4 × 3 − 1 = 4 × 2 = 3 4 \div 3 = 4 \times 3^{-1} = 4 \times 2 = 3 4 ÷ 3 = 4 × 3 − 1 = 4 × 2 = 3 。 看上有点神乎其神,4 ÷ 3 4 \div 3 4 ÷ 3 甚至不是整数,怎么可能答案是 3 3 3 ???别忘了,剩余系中的每一个元素都对应一个同余等价类,所以 4 ÷ 3 = 3 4 \div 3 = 3 4 ÷ 3 = 3 的实际含义是:“假定有两个整数 a , b a, b a , b , 满足 a b \frac{a}{b} b a 是整数,且 a , b a, b a , b 除以 5 5 5 的余数分别是 4 4 4 和 3 3 3 ,那么 a b \frac{a}{b} b a 除以 5 5 5 的余数等于 3 3 3 ”,比如 a = 9 , b = 3 a = 9, b = 3 a = 9 , b = 3 时就成立。
线性模方程 线性模方程是下面这个玩意,其中 x x x 是未知数,我们要干的事情就是求出 x x x 在 Z m Z_m Z m 中的解集。
a x ≡ b ( mod m )
ax\equiv b \pmod{m}
a x ≡ b ( modm )因为同余,所以有 a x − b = y m ax - b = ym a x − b = y m ,即 a x − m y = b ax - my = b a x − m y = b ,这个方程有解当且仅当 gcd ( a , m ) ∣ b \gcd(a, m) \mid b g cd( a , m ) ∣ b 。这是第一步。 假设 a a a 的逆在模 m m m 意义下存在,为 a − 1 a^{-1} a − 1 ,那么根据基本性质,两边可以同乘 a − 1 a^{-1} a − 1 ,则得到 x ≡ b × a − 1 ( mod m ) x\equiv b\times a^{-1} \pmod{m} x ≡ b × a − 1 ( modm ) ,是不是这样,问题就轻松解决了呢?并不是,a a a 的逆极有可能在模 m m m 意义下不存在,我们试着求一下在模 m m m 意义下 a a a 的逆。即解
a x ≡ 1 ( mod m )
ax \equiv 1 \pmod m
a x ≡ 1 ( modm )转化:
a x − 1 = m y
ax - 1 = my
a x − 1 = m y 移项:
a x − m y = 1
ax - my = 1
a x − m y = 1 根据扩展欧几里得算法,当且仅当 gcd ( a , m ) = 1 \gcd(a, m) = 1 g cd( a , m ) = 1 ,模 m m m 意义下 a a a 的逆存在。所以,我们要解 a x ≡ b ( mod m ) ax\equiv b \pmod{m} a x ≡ b ( modm ) ,必须将其转化,使得 a a a 的乘法逆存在。
将 a x − m y = b ax - my = b a x − m y = b 两边同时除以 gcd ( a , m ) \gcd(a, m) g cd( a , m ) ,得到:
a ′ x − m ′ y = b ′ ( a ′ = a gcd ( a , m ) , m ′ = m gcd ( a , m ) , b ′ = b gcd ( a , m ) )
a'x - m'y = b'(a' = \frac{a}{\gcd(a, m)}, m' = \frac{m}{\gcd(a, m)}, b' = \frac{b}{\gcd(a, m)})
a ′ x − m ′ y = b ′ ( a ′ = g cd( a , m ) a , m ′ = g cd( a , m ) m , b ′ = g cd( a , m ) b ) 于是问题回到了求解:
a ′ x ≡ b ′ ( mod m ′ )
a'x \equiv b' \pmod {m'}
a ′ x ≡ b ′ ( modm ′ )这一回,我们能保证 gcd ( a ′ , m ′ ) = 1 \gcd(a', m') = 1 g cd( a ′ , m ′ ) = 1 ,所以 a a a 在这里一定有乘法逆!
那么这个方程的解是在 Z m ′ Z_{m'} Z m ′ 剩余系内的:
x ≡ ( a ′ ) − 1 b ′ ( mod m ′ )
x\equiv (a')^{-1}b' \pmod {m'}
x ≡ ( a ′ ) − 1 b ′ ( modm ′ )但是我们需要求解的是 Z m Z_{m} Z m 剩余系内的元素,怎么转换过去呢?设 p = ( a ′ ) − 1 b ′ p = (a')^{-1}b' p = ( a ′ ) − 1 b ′ ,那么我们有无穷多个实数解:x = p , p + m ′ , p + 2 m ′ , p + 3 m ′ . . . x = p, p + m', p + 2m', p + 3m'... x = p , p + m ′ , p + 2 m ′ , p + 3 m ′ . . . 。我们想要知道,这无穷多个实数解,在模 m m m 意义下究竟有多少个等价类(即模 n n n 会有多少个不同的余数)?大家可能已经发现了,正好 d = gcd ( a , m ) d = \gcd(a, m) d = g cd( a , m ) 个,分别为 p , p + m ′ , p + 2 m ′ , . . . , p + ( d − 1 ) m ′ p, p + m', p + 2m',...,p + (d - 1)m' p , p + m ′ , p + 2 m ′ , . . . , p + ( d − 1 ) m ′ 。 为什么呢?假设 p + i m ′ p + im' p + i m ′ 与 p + j m ′ p + jm' p + j m ′ 模 m m m 同余,那么 ( p + i m ′ ) − ( p + j m ′ ) = ( i − j ) m ′ (p + im') - (p + jm') = (i - j)m' ( p + i m ′ ) − ( p + j m ′ ) = ( i − j ) m ′ ,必定是 m m m 的倍数,也就是 i − j i - j i − j 是 d d d 的倍数。所以是 d d d 个一轮回的!p , p + d m ′ , p + 2 d m ′ , . . . p, p + dm', p + 2dm',... p , p + d m ′ , p + 2 d m ′ , . . . 这些数模 m m m 同余;p + m ′ , p + ( d + 1 ) m ′ , p + ( 2 d + 1 ) m ′ , . . . p + m', p + (d + 1)m', p + (2d + 1)m',... p + m ′ , p + ( d + 1 ) m ′ , p + ( 2 d + 1 ) m ′ , . . . 这些数模 m m m 同余; ...p + ( d − 1 ) m ′ , p + ( d + d − 1 ) m ′ , p + ( 2 d + d − 1 ) m ′ , . . . p + (d - 1)m', p + (d + d - 1)m', p + (2d + d - 1)m',... p + ( d − 1 ) m ′ , p + ( d + d − 1 ) m ′ , p + ( 2 d + d − 1 ) m ′ , . . . 这些数模 m m m 同余; 而
'
之间不可能同余,因为不满足 i − j i - j i − j 是 d d d 的倍数。所以,方程 a x ≡ b ( mod m ) ax\equiv b \pmod{m} a x ≡ b ( modm ) 要么无解,要么恰有 gcd ( a , m ) \gcd(a, m) g cd( a , m ) 个解。
总结起来,解线性同余方程只需要求 a a a 的乘法逆,但分析过程还是有些恼人的。
中国剩余定理 现在如果有多个同余方程,即同余方程组,变量只有一个,且 x x x 前面系数为 1 1 1 , 任意 m i m_i m i 之间互素,该怎么做呢? 中国剩余定理在这里派上用场了,它并不是一种算法,而是一种思考、构造的方法。
现在有方程组 x ≡ a i ( mod m i ) x\equiv a_i \pmod {m_i} x ≡ a i ( modm i ) 。我们令 M = ∏ m i M = \prod m_i M = ∏ m i ,w i = M m i w_i = \frac{M}{m_i} w i = m i M 。那么解一定可以表示为 Z M Z_M Z M 剩余系中的一个元素,即 x ≡ b ( mod M ) x\equiv b\pmod M x ≡ b ( modM ) 。我们来构造这个解。
由于 m i m_i m i 之间互素,可以得到 gcd ( m i , w i ) = 1 \gcd(m_i, w_i) = 1 g cd( m i , w i ) = 1 ,构造出这样一个方程 w i p i + m i q i = 1 w_ip_i + m_iq_i = 1 w i p i + m i q i = 1 ,由于 gcd ( m i , w i ) = 1 \gcd(m_i, w_i) = 1 g cd( m i , w i ) = 1 ,此方程一定有解。用扩展欧几里得算法解出 p i , q i p_i, q_i p i , q i ,令 e i = w i p i e_i = w_ip_i e i = w i p i ,现在有一些有趣的性质,方程两边都模 m i m_i m i ,得到 e i mod m i + 0 = 1 e_i \bmod m_i + 0 = 1 e i modm i + 0 = 1 即 e i mod m i = 1 e_i \bmod m_i = 1 e i modm i = 1 。
依据这一性质,我们构造得到方程在 Z M Z_M Z M 剩余系中的唯一解 x ≡ e 1 a 1 + e 2 a 2 + . . . + e n a n ( mod M ) x \equiv e_1a_1 +e_2a_2 +...+e_na_n\pmod M x ≡ e 1 a 1 + e 2 a 2 + . . . + e n a n ( modM ) 。验证一下,只需把每个方程带进去,看是否都成立即可。对于 x ≡ a i ( mod m i ) x\equiv a_i \pmod {m_i} x ≡ a i ( modm i ) ,将得到的解右边模 m i m_i m i ,惊奇的发现,除了 e i a i e_ia_i e i a i 这一项的结果为 a i a_i a i 之外,其余项的结果都是 0 0 0 。
x ≡ 0 + 0 + . . + 1 × a i + 0 + . . + 0 ( mod m i )
x \equiv 0 + 0 + ..+ 1 \times a_i + 0 + .. + 0 \pmod {m_i}
x ≡ 0 + 0 + . . + 1 × a i + 0 + . . + 0 ( modm i )原因是 e i mod m i = 1 e_i \bmod m_i = 1 e i modm i = 1 一模变成 1 1 1 ,还有
中 w j w_j w j 必定含有因子 m i m_i m i ,所以一模就成 0 0 0 了。
则对于每一个 m i m_i m i ,我们都能得到一个与原方程组一模一样的同余等式,所以这个解是正确的。
所以 x 0 = e 1 a 1 + e 2 a 2 + . . . + e n a n x_0 = e_1a_1 +e_2a_2 +...+e_na_n x 0 = e 1 a 1 + e 2 a 2 + . . . + e n a n 显然是一个实数解,x 0 + M , x 0 + 2 M , x 0 + 3 M . . . . x_0 + M, x_0 +2M, x_0 + 3M.... x 0 + M , x 0 + 2 M , x 0 + 3 M . . . . 都是解,原方程组有无穷组实数解。
欧拉定理 在数论中,欧拉定理是一个关于同余的性质。欧拉定理表明,若 n , a n, a n , a 为正整数,且 n , a n,a n , a 互素,则:
a φ ( n ) ≡ 1 ( mod n ) a^{\varphi(n)} \equiv 1 \pmod n a φ ( n ) ≡ 1 ( modn )特别的,当 n n n 为素数的时候,a a a 可取任意 Z n Z_n Z n 内元素。由于 φ ( n ) = n − 1 \varphi(n) = n - 1 φ ( n ) = n − 1 ,故有:
a n − 1 ≡ 1 ( mod n ) a n ≡ a ( mod n )
\begin{aligned}a^{n - 1} \equiv 1 \pmod n\\a^n \equiv a \pmod n\end{aligned}
a n − 1 ≡ 1 ( modn ) a n ≡ a ( modn ) 这就是费马小定理。观察到右边 1 1 1 的存在,发现与之前所说的逆元有一点相似:
a x ≡ 1 ( mod n )
ax\equiv 1\pmod n
a x ≡ 1 ( modn )x x x 是逆元,根据费马小定理,有 x ≡ a n − 2 ( mod n ) x \equiv a^{n-2} \pmod n x ≡ a n − 2 ( modn ) ,故可以快速幂在 O ( log n ) O(\log n) O ( log n ) 的时间内快速求出任意 Z n Z_n Z n 内元素的逆元,但只有在 n n n 是素数的时候才起作用。
离散对数 当 n n n 为素数的时候,解模方程:
a x ≡ b ( mod n ) a^x\equiv b\pmod n a x ≡ b ( modn )如果是实数范围内,答案是 log a b \log_ab log a b ,可惜并不是,这里采用一种精妙的解决办法。 解:根据欧拉定理有:a n − 1 ≡ 1 ( mod n ) a^{n - 1}\equiv 1\pmod n a n − 1 ≡ 1 ( modn ) ,又 a 0 ≡ 1 ( mod n ) a^0\equiv 1\pmod n a 0 ≡ 1 ( modn ) ,所以 a x a^x a x 在模 n n n 剩余系内的值无限循环,以 a 0 , a 1 , . . . , a n − 2 a^0, a^1,...,a^{n-2} a 0 , a 1 , . . . , a n − 2 为循环节。 所以,只需检查 x = 0 , 1 , 2 , . . . , n − 2 x = 0, 1, 2,..., n - 2 x = 0 , 1 , 2 , . . . , n − 2 时是不是解即可。但这样复杂度是 O ( n ) O(n) O ( n ) 的,下面用一种构造手段将复杂度降下来: 我们先检查前 m m m 项(m m m 取值稍后说明),即 a 0 , a 1 , . . . , a m − 1 a^0, a^1,...,a^{m - 1} a 0 , a 1 , . . . , a m − 1 模 n n n 的值是否为 b b b ,并把 a i mod n a^i\bmod n a i modn 的值保存在 e i e_i e i 中,求出 a m a^m a m 逆 a − m a^{-m} a − m 。 下面接着考虑 a m , a m + 1 , . . . , a 2 m − 1 a^m, a^{m + 1},...,a^{2m - 1} a m , a m + 1 , . . . , a 2 m − 1 ,这次不需要检查,如果他们当中存在解,说明存在 i ( 0 ≤ i < m ) i(0\le i<m) i ( 0 ≤ i < m ) 使得 e i a m ≡ b ( mod n ) e_ia^m\equiv b\pmod n e i a m ≡ b ( modn ) 。两边乘 a − m a^{-m} a − m ,得到 e i ≡ b a − m ( mod n ) e_i\equiv ba^{-m}\pmod n e i ≡ b a − m ( modn ) ,也就是说我们只需要检查有没有一个 i i i ,使得 e i ≡ b a − m ( mod n ) e_i\equiv ba^{-m}\pmod n e i ≡ b a − m ( modn ) ,这相当于依次检查了 a m , a m + 1 , . . . , a 2 m − 1 a^m, a^{m + 1},...,a^{2m - 1} a m , a m + 1 , . . . , a 2 m − 1 。 如果仍然没有检查到解,这回考虑 a 2 m , a 2 m + 1 , . . . , a 3 m − 1 a^{2m}, a^{2m + 1},...,a^{3m - 1} a 2 m , a 2 m + 1 , . . . , a 3 m − 1 ,同样的,我们只需要检查有没有一个 i i i ,使得 e i ≡ b ( a − m ) 2 ( mod n ) e_i\equiv b(a^{-m})^2\pmod n e i ≡ b ( a − m ) 2 ( modn ) ,这相当于依次检查了 a 2 m , a 2 m + 1 , . . . , a 3 m − 1 a^{2m}, a^{2m + 1},...,a^{3m - 1} a 2 m , a 2 m + 1 , . . . , a 3 m − 1 。 显然使用 STL 中的 MAP 可以帮我们快速完成检测操作。预处理出 e i e_i e i 的复杂度是 O ( m log m ) O(m\log m) O ( m log m ) ,求出 a − m a^{-m} a − m 的复杂度是 log n \log n log n ,一共有 n / m n/m n / m 轮检测,每轮复杂度 log m \log m log m 。总复杂度 O ( ( m + n m ) log m ) O((m + \frac{n}{m})\log m) O ( ( m + m n ) log m ) ,当 m = n m = \sqrt n m = √ n 时,复杂度最低为:O ( n log n ) O(\sqrt n\log n) O ( √ n log n )
指数循环节 a x ≡ b ( mod n ) a^{x} \equiv b \pmod n a x ≡ b ( modn )当 x x x 大到一定程度的时候,我们没有办法算 b b b 了,这时需要用到指数循环节。 如果 gcd ( a , n ) = 1 \gcd(a, n) = 1 g cd( a , n ) = 1 ,由欧拉定理 a φ ( n ) ≡ 1 ( mod n ) a^{\varphi(n)} \equiv 1 \pmod n a φ ( n ) ≡ 1 ( modn ) 可知指数以 [ 0 , φ ( n ) − 1 ] [0, \varphi(n) - 1] [ 0 , φ ( n ) − 1 ] 为循环节不断循环,故有
a x ≡ a x mod φ ( n ) ( mod n ) a^{x} \equiv a^{x \bmod \varphi(n)} \pmod n a x ≡ a x modφ ( n ) ( modn )如果
,似乎不好做了,不过也有公式!
a x ≡ a x mod φ ( n ) + φ ( n ) ( mod n ) ( x ≥ φ ( n ) ) a^x\equiv a^{x \bmod \varphi(n) + \varphi(n)} \pmod n (x\ge \varphi(n)) a x ≡ a x modφ ( n ) + φ ( n ) ( modn )( x ≥ φ ( n ) ) 需要声明一下,只有 x ≥ φ ( n ) x\ge \varphi(n) x ≥ φ ( n ) 时此公式成立,所以千万不要盲目的取余了再加!