求解线性同余方程组

求解线性同余方程组

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

{ 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} a1xb1 (mod m1)a2xb2 (mod m2)               anxbn (mod mn)

与扩展中国剩余定理的证明类似,首先找出一个形如这样的方程: x ≡ b 0   ( m o d   m 0 ) x\equiv b_0\ (mod\ m_0) xb0 (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} {xb0 (mod m0)a1xb1 (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=b1a1b0+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)b1a1b0+(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 b1a1b0,否则方程无解)

所以有: 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)b1a1b0 (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)b1a1b0inv((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)b1a1b0inv((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)b1a1b0inv((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)b1a1b0inv((a1m0,m1)a1m0,(a1m0,m1)m1)m0+b0 (mod (a1m0,m1)m0m1)

此时可以将方程看作: x ≡ b   ( m o d   m ) x\equiv b\ (mod\ m) xb (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)b1a1b0inv((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);
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值