问题:给定正整数(m_1, m_2, ... , m_n) 和 (a_1, a_2, ... , a_n) 求关于 x 的同余方程组的一个解:
[left{
egin{aligned}
x equiv a_1 pmod {m_1}
\
x equiv a_2 pmod {m_2}\
vdots qquad qquad quad quad
\
x equiv a_n pmod {m_n}
end{aligned}
ight.
]
其中,(m_1, m_2, ..., m_n) 两两互质。
令 (m = prod_{i = 1}^n m_i) , (M_i = frac{m}{m_i}),(t_i) 为 (M_i) 在模 (m_i) 下的逆元,即:(M_i cdot t_i equiv 1 pmod{m_i})
则 x 的一个解为:
[egin{aligned}
x = sum_{i = 1}^n a_i M_i t_i
end{aligned}
]
方程的通解为 : (X = x + kcdot m quad (k in Z))
证明:
因为(M_i = frac{m}{m_i}),(M_i) 是除 (m_i) 以外所有模数的倍数,所以总是存在:
[egin{aligned}
a_icdot M_i cdot t_i equiv 0 pmod{m_j} quad (j
e i)
\
a_i cdot M_i cdot t_i equiv a_i pmod{m_i} quad qquad
end{aligned}
]
所以将所有 (a_iM_it_i) 累加起来,就可以满足方程组中的所有方程
实现:一个for循环,用exgcd求逆元。
以下代码中,a[i] 相当于(m_i) b[i] 相当于 (a_i)
int exgcd(lld a, lld b, lld &x, lld &y) {
if(b == 0) {
x = 1, y = 0; return a;
}
int g = exgcd(b, a % b, x, y);
lld p = x; x = y; y = p - a / b * y;
return g;
}
void crt() {
lld mi, ti, y;
for(int i = 1; i <= n; i++) {
mi = m / a[i];
exgcd(mi, a[i], ti, y);
ans = (ans + (b[i] * mi * ti) % m + m) % m;
}
}