同余方程和中国剩余定理

今天做题的时候化简式子,化简到一半发现几乎就是中国剩余定理的板题,然后发现蒟蒻我不会写中国剩余定理,然后就来补习了23333333

解线性模方程

解法

\( ax \equiv b \mod q \) 可以转化为\( ax + kq = b \) 。

当\( gcd(a,q)|b \) 时,方程有解,否则无解。

当\( a \) 和\( q \) 不互质时,令方程两边同时处以\( gcd(a,q) \) ,得到:

\( \dfrac{a}{gcd(a,q)}x+k\dfrac{q}{gcd(a,q)}=\dfrac{b}{gcd(a,q)} \)

也就是:

\( \dfrac{ax}{gcd(a,q)} \equiv \dfrac{b}{gcd(a,q)} \mod \dfrac{q}{gcd(a,q)} \)

令\( a_1=\dfrac{a}{gcd(a,q)},b_1=\dfrac{b}{gcd(a,q)},q_1=\dfrac{q}{gcd(a,q)} \) ,于是有:

\( a_1x \equiv b_1 \mod q_1 \) ,其中\( a_1 \) 和\( q_1 \) 互质。此时,在方程两边乘\( a_1 \) 在模\( q_1 \) 意义下的逆元,就可以得到:

\( x\equiv b_1\cdot a_1^{-1} \mod q_1 \)

所以\( x=b_1\cdot a_1^{-1} + k\cdot q_1 \) ,其中\( k\in Z^+ \)

等价类

对于上式\( x=b_1\cdot a_1^{-1} + k\cdot q_1 \) ,对于任意\( i,j\in Z^+,i \geqslant j \) ,显然,我们有:

\( (b_1\cdot a_1^{-1}+i\cdot q_1)-(b_1\cdot a_1^{-1} + j\cdot q_1)= (i-j)q_1 \)

如果\( (b_1\cdot a_1^{-1}+i\cdot q_1) \) 和\( (b_1\cdot a_1^{-1} + j\cdot q_1) \) 同余,那么\( (i-j)q_1 \) 是\( q \) 的倍数。因此,\( (i-j) \) 必须是\( gcd(a,q) \) 的倍数。

换句话说,在模\( q \) 的剩余系下,\( ax \equiv b \mod q \) 恰好有\( gcd(a,q) \) 个解。令\( t = b_1\cdot a_1^{-1} \) ,则这\( gcd(a,q) \) 个解分别是:\( t, t+p_1 , t + 2p_1, \cdots , t + (gcd(a,q)-1)p_1 \) 。

这里稍作解释:为什么说,在模\( q \) 的剩余系下,只有这\( gcd(a,q) \) 个解呢?

考虑\( x_1=t \) 和\( x_2=t+gcd(a,q)p_1 \) ,由上面的定义可知:\( gcd(a,q)p_1=p \) 。所以,\( ax_1 \mod p \) 和\( ax_2 \mod p \) 在任何意义下都是完全一致的。同理可得其他\( x=t + kp_1 \) 的情况。所以,只保留这\( gcd(a,q) \) 个解就能涵盖所有的情况。

解同余方程组(中国剩余定理)

变量还是一个,但是变成了如下的方程组:

\begin{cases} x \equiv a_1 \mod m_1 \cr x\equiv a_2 \mod m_2 \cr \cdots \cr x\equiv a_n \mod m_n \end{cases}

假设此时所有的\( m_i \) 两两互质。令\( M=\prod\limits_{i=1}^{n}m_i,w_i=\dfrac{M}{m_i} \) (\( w_i \) 就是除了\( m_i \) 以外其他\( m \) 的乘积),那么有\( gcd(w_i, m_i)=1 \) (\( w_i \) 和\( m_i \) 互质)。

所以,我们很容易求出\( w_i \) 在模\( m_i \) 意义下的逆元:

\( t_iw_i + ym_i = 1 \) ,拓展欧几里得算法可以求出\( t_i \) 。

所以,显然有\( t_iw_i \equiv 1 \mod m_i \) (\( t_i \) 是\( w_i \) 的逆元)。

也就是:

\( t_iw_i = km_i + 1, k\in Z \) ,等价于

\( t_iw_i + km_i = 1, k \in Z \)

两边同时乘\( a_i \) ,得:

\( t_ia_iw_i + ka_im_i = a_i \)

我们知道,\( k \) 表示的是模\( m_i \) 的次数,所以我们可以把\( ka_i \) 看作\( k \) 。

于是我们得到:

\( t_ia_iw_i + km_i = a_i \)

又因为我们有:\( x \equiv a_i \mod m_i \) (看题干),也就是:

\( x = a_i + km_i \)
\( x + km_i = a_i \)

所以,我们得到如下方程组:

\( \begin{cases} t_ia_iw_i + km_i = a_i \cr x + km_i = a_i \end{cases} \)

注意这里两个\( k \) 不一定相等,但是因为我们要保证的是\( x \) 对\( m_i \) 取模的结果是\( a_i \) ,所以整数\( k \) 对结果并没有影响(因为它们的乘数是\( m_i \) )。所以我们得到:\( x=t_ia_iw_i \) 。

由定义可知,对于任意\( j \neq i \) ,恒有\( m_j | w_i \) 。

所以,由取模的性质,对于任意的整数\( j \) 有:

\( \begin{align} & \sum\limits_{i=1}^{n}t_ia_iw_i \mod m_j \cr = &\left( t_ja_jw_j + \sum\limits_{i=1}^{j-1}t_ia_iw_i + \sum\limits_{i=j+1}^{n}t_ia_iw_i\right) \mod m_j \cr = & t_ja_jw_j \mod m_j + \sum\limits_{i=1}^{j-1}t_ia_iw_i \mod w_j+ \sum\limits_{i=j+1}^{n}t_ia_iw_i \mod w_j \cr = &t_ja_jw_j \mod m_j \cr = & a_j\end{align} \)

(因为\( m_j | w_i \) ,所以\( \sum\limits_{i=1}^{j-1}t_ia_iw_i \mod w_j = 0 \) ,\( \sum\limits_{i=j+1}^{n}t_ia_iw_i \mod m_j = 0 \) )

所以,\( x \) 的一组解就是\( \sum\limits_{i=1}^{n}t_ia_iw_i \) ,其中\( t_i \) 是\( w_i \) 关于模\( m_i \) 的逆元。

在模\( M \) 的剩余系下,方程组就有唯一一组解:\( \sum\limits_{i=1}^{n}t_ia_iw_i \mod M \) 。

代码如下:

// 测试代码

#include <cstdio>
typedef long long ll;

ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (b == 0) {
		x = 1;
		y = 0; 
		return a;
	}
	ll r = exgcd(b, a % b, x, y);
	ll t = x;
	x = y;
	y = t - a / b * y;
	return r;
}

// n个方程:x = a[i] % m[i], (0 <= i < n)
ll CRT(int n, int *a, int *m) {
    ll M = 1, t, y, x = 0;
    for (int i = 0; i < n; i++) M *= m[i];
    for (int i = 0; i < n; i++) {
        ll w = M / m[i];
        exgcd(w, m[i], t, y);
		x = ((x + t * w * a[i]) % M + M) % M;
    }
    return x;
}

int a[1000], m[1000];

int main() {
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d", a + i);
	for (int i = 0; i < n; i++)
		scanf("%d", m + i);
	printf("%lld\n", CRT(n, a, m));
	return 0;
}

参考资料:

中国剩余定理证明

刘汝佳《算法竞赛入门经典——训练指南》


本文迁移自作者原博客:icysky's Blog
本文作者:icysky
原文链接:同余方程和中国剩余定理
版权声明:本博客所有文章除特别声明外,均采用CC-BY-NC-SA 4.0许可协议。icysky's Blog 版权所有,转载请注明出处。

posted @ 2020-05-13 22:43  icysky  阅读(335)  评论(0编辑  收藏  举报