线性同余方程组就是形如这样的方程组:
{ a 1 x ≡ b 1 ( m o d m 1 ) a 2 x ≡ b 2 ( m o d m 2 ) ⋮ a n x ≡ b n ( m o d m n ) \begin{cases} a_1x\equiv b_1\ (mod\ m_1)\\ a_2x\equiv b_2\ (mod\ m_2)\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \vdots \\ a_nx\equiv b_n\ (mod\ m_n)\\ \end{cases} ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a1x≡b1 (mod m1)a2x≡b2 (mod m2) ⋮anx≡bn (mod mn)
与扩展中国剩余定理的证明类似,首先找出一个形如这样的方程: x ≡ b 0 ( m o d m 0 ) x\equiv b_0\ (mod\ m_0) x≡b0 (mod m0)
可以化为: x = b 0 + m 0 k 0 x=b_0+m_0k_0 x=b0+m0k0
第一步可以假定 b 1 = 0 , m 1 = 1 b_1=0,m_1=1 b1=0,m1=1 ,代表解是所有的正整数。
之后与方程组的第一个方程联立:
{ x ≡ b 0 ( m o d m 0 ) a 1 x ≡ b 1 ( m o d m 1 ) \begin{cases} x\equiv b_0\ (mod\ m_0)\\ a_1x\equiv b_1\ (mod\ m_1) \end{cases} {x≡b0 (mod m0)a1x≡b1 (mod m1)
把一式带入二式得:$ a 1 ( b 0 + m 0 k 0 ) ≡ b 1 ( m o d m 1 ) a_1(b_0+m_0k_0)\equiv b_1\ (mod\ m_1) a1(b0+m0k0)≡b1 (mod m1)
a 1 b 0 + a 1 m 0 k 0 = b 1 + m 1 k 1 a_1b_0+a_1m_0k_0=b_1+m_1k_1 a1b0+a1m0k0=b1+m1k1
a 1 m 0 k 0 = b 1 − a 1 b 0 + m 1 k 1 a_1m_0k_0=b_1-a_1b_0+m_1k_1 a1m0k0=b1−a1b0+m1k1
此时令 ( a , b ) (a, b) (a,b)表示 g c d ( a , b ) gcd(a,b) gcd(a,b),则有:
a 1 m 1 ( a 1 m 0 , m 1 ) k 0 = b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) + m 1 ( a 1 m 0 , m 1 ) k 1 \frac{a_1m_1}{(a_1m_0,m_1)}k_0=\frac{b_1-a_1b_0}{(a_1m_0,m_1)}+\frac{m_1}{(a_1m_0,m_1)}k_1 (a1m0,m1)a1m1k0=(a1m0,m1)b1−a1b0+(a1m0,m1)m1k1
(此时 ( a 1 m 0 , m 1 ) (a_1m_0,m_1) (a1m0,m1)一定要能够整除 b 1 − a 1 b 0 b_1-a_1b_0 b1−a1b0,否则方程无解)
所以有: a 1 m 0 ( a 1 m 0 , m 1 ) k 0 ≡ b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) ( m o d m 1 ( a 1 m 0 , m 1 ) ) \frac{a_1m_0}{(a_1m_0,m_1)}k_0\equiv \frac{b_1-a_1b_0}{(a_1m_0,m_1)}\ (mod\ \frac{m_1}{(a_1m_0,m_1)}) (a1m0,m1)a1m0k0≡(a1m0,m1)b1−a1b0 (mod (a1m0,m1)m1)
k 0 ≡ b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) i n v ( a 1 m 0 ( a 1 m 0 , m 1 ) , m 1 ( a 1 m 0 , m 1 ) ) ( m o d m 1 ( a 1 m 0 , m 1 ) ) k_0\equiv \frac{b_1-a_1b_0}{(a_1m_0,m_1)}inv(\frac{a_1m_0}{(a_1m_0,m_1)},\frac{m_1}{(a_1m_0,m_1)})\ (mod\ \frac{m_1}{(a_1m_0,m_1)}) k0≡(a1m0,m1)b1−a1b0inv((a1m0,m1)a1m0,(a1m0,m1)m1) (mod (a1m0,m1)m1)
k 0 = b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) i n v ( a 1 m 0 ( a 1 m 0 , m 1 ) , m 1 ( a 1 m 0 , m 1 ) ) + y m 1 ( a 1 m 0 , m 1 ) k_0=\frac{b_1-a_1b_0}{(a_1m_0,m_1)}inv(\frac{a_1m_0}{(a_1m_0,m_1)},\frac{m_1}{(a_1m_0,m_1)})+y\frac{m_1}{(a_1m_0,m_1)} k0=(a1m0,m1)b1−a1b0inv((a1m0,m1)a1m0,(a1m0,m1)m1)+y(a1m0,m1)m1
代入高亮的上式:
x = b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) i n v ( a 1 m 0 ( a 1 m 0 , m 1 ) , m 1 ( a 1 m 0 , m 1 ) ) m 0 + y m 0 m 1 ( a 1 m 0 , m 1 ) + b 0 x=\frac{b_1-a_1b_0}{(a_1m_0,m_1)}inv(\frac{a_1m_0}{(a_1m_0,m_1)},\frac{m_1}{(a_1m_0,m_1)})m_0+y\frac{m_0m_1}{(a_1m_0,m_1)}+b_0 x=(a1m0,m1)b1−a1b0inv((a1m0,m1)a1m0,(a1m0,m1)m1)m0+y(a1m0,m1)m0m1+b0
x ≡ b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) i n v ( a 1 m 0 ( a 1 m 0 , m 1 ) , m 1 ( a 1 m 0 , m 1 ) ) m 0 + b 0 ( m o d m 0 m 1 ( a 1 m 0 , m 1 ) ) x\equiv \frac{b_1-a_1b_0}{(a_1m_0,m_1)}inv(\frac{a_1m_0}{(a_1m_0,m_1)},\frac{m_1}{(a_1m_0,m_1)})m_0+b_0\ (mod\ \frac{m_0m_1}{(a_1m_0,m_1)}) x≡(a1m0,m1)b1−a1b0inv((a1m0,m1)a1m0,(a1m0,m1)m1)m0+b0 (mod (a1m0,m1)m0m1)
此时可以将方程看作: x ≡ b ( m o d m ) x\equiv b\ (mod\ m) x≡b (mod m)
其中 b = ( b 1 − a 1 b 0 ( a 1 m 0 , m 1 ) i n v ( a 1 m 0 ( a 1 m 0 , m 1 ) , m 1 ( a 1 m 0 , m 1 ) ) ) % m 1 ( a 1 m 0 , m 1 ) m 0 + b 0 b=(\frac{b_1-a_1b_0}{(a_1m_0,m_1)}inv(\frac{a_1m_0}{(a_1m_0,m_1)},\frac{m_1}{(a_1m_0,m_1)}))\%\frac{m_1}{(a_1m_0,m_1)}m_0+b_0 b=((a1m0,m1)b1−a1b0inv((a1m0,m1)a1m0,(a1m0,m1)m1))%(a1m0,m1)m1m0+b0
m = m 0 m 1 ( a 1 m 0 , m 1 ) m=\frac{m_0m_1}{(a_1m_0,m_1)} m=(a1m0,m1)m0m1
到这里,式子里所有的值我们都知道了,并且得到了一个新的同余式。再把新的和其他的联立,依此循环,最终求出通解。
//返回一个(b,m)的数对
pair<int, int>linear_congruence(const vector<int>&A, const vector<int>&B, const vector<int>&M) {
//由于最开始没有任何限制,所以先把解设为表示所有整教的 x三0(mod 1)
int b = 0, m = 1;
for (int i = 0; i < A.size(); i++) {
int a = A[i] * m, b = B[i] - A[i] * b, d = gcd(M[i], a);
if (b%d != 0) return make_pair(0, -1);//无解
int t = b / d * mod_inverse(a / d, M[i] / d) % (M[i] / d);
b = b + m * t;
m *= M[i] / d;
}
return make_pair(x % m, m);
}