求解线性同余方程组

求解线性同余方程组

线性同余方程组就是形如这样的方程组:

{ 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}

与扩展中国剩余定理的证明类似,首先找出一个形如这样的方程: x b 0   ( m o d   m 0 ) x\equiv b_0\ (mod\ m_0)

可以化为: x = b 0 + m 0 k 0 x=b_0+m_0k_0

第一步可以假定 b 1 = 0 , m 1 = 1 b_1=0,m_1=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}

把一式带入二式得:$ 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)

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

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

此时令 ( a , b ) (a, b) 表示 g c d ( 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

(此时 ( a 1 m 0 , m 1 ) (a_1m_0,m_1) 一定要能够整除 b 1 a 1 b 0 b_1-a_1b_0 ,否则方程无解)

所以有: 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)})

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)})

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)}

代入高亮的上式:

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 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 b   ( m o d   m ) x\equiv 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

m = m 0 m 1 ( a 1 m 0 , m 1 ) m=\frac{m_0m_1}{(a_1m_0,m_1)}

到这里,式子里所有的值我们都知道了,并且得到了一个新的同余式。再把新的和其他的联立,依此循环,最终求出通解。

代码

//返回一个(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);
}

发布了163 篇原创文章 · 获赞 54 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42856843/article/details/102644903
今日推荐