以前的blog好像写错了……(懒得改了)
重新学了一遍~
· 引入
求解上述关于 $x$ 的方程组。(参考 #hihocoder 1303#)
此类方程组称为 模线性方程组。求解此类问题的一般方法就是扩展中国剩余定理,当然方程组可能无解。
· 扩展中国剩余定理
- 前置
① 扩展欧几里得定理;
② 同余方程;
- 推导
首先我们考虑 $n=2$ ,即方程组只有两个式子。
根据同余的定义,我们可以写出:
所以有 $k_1m_1+r_1=k_2m_2+r_2$ ;
移项得:$k_1m_1-k_2m_2=r_2-r_1$ ;
令 $g=\gcd(m_1,m_2)$ ,将上式两边同时除以 $g$ ,得: $\frac{m_1}{g}k_1-\frac{m_2}{g}k_2=\frac{r_2-r_1}{g}$ ;
(★)因为上式的左边一定是整数,如果右边是分数,即 $g\not| r_2-r_1$ ,方程就无解;反之方程有解;
判断如果有解,则有 $\frac{m_1}{g}k_1-\frac{m_2}{g}k_2=\frac{r_2-r_1}{g}$ 。
因为 $\gcd(\frac{m_1}{g},\frac{m_2}{g})=1$,通过扩展欧几里得定理我们可以得到一组 $(k_1’,k_2’)$ 满足 $\frac{m_1}{g}k_1’+\frac{m_2}{g}k_2’=1$ ;
再将上式两边同时乘以 $t=\frac{r_2-r_1}{g}$ ,得:$\frac{m_1}{g}(k_1’t)-\frac{m_2}{g}(k_2’t)=t$ ;
则有:
那么就可以得到 $x$ 的一个最小解 $x=k_1m_1+r_1$ ;
令 $l$ 为 $m_1,m_2$ 的最小公倍数,根据这个解我们可以得到一个解集:$X=\{kl+x|k\in R\}$ ;
则对于 $X_i\in X$ 有 $X_i\equiv x\pmod{l}$ ;
- C++实现
显然可以递推,设上一步得到了 $x\equiv R\pmod{M}$;则有:
通过欧几里得定理得到 g=GCD(M,m[i])
;
定义 C=r[i]-R
;
根据扩展中国剩余定理,若 C%g!=0
,则无解;
否则通过扩展欧几里得定理EXGCD(M/g,m[i]/g,k1,k2)
,可以得到 k1
;
然后 x=(C/g*k1)%(m[i]/g)
得到 x 的最小解。
更新 R,M :R=R+x*M
,M=M*m[i]/g
(也就是M和m[i]的最小公倍数);
使 R 的绝对值尽可能小:R=R%M
。
- 伪代码
1 | M=m[1],R=r[1] |
· 源代码
(以 hihocoder 1303 为参考)
1 | /*Lucky_Glass*/ |
The End
Thanks for reading!
Email: lucky_glass@foxmail.com ,欢迎提问~