中国剩余定理

定理内容

中国剩余定理最早记载于《孙子算经》的“物不知数”问题,所以又叫做孙子剩余定理。
m 1 , m 2 , m 3 , ⋯   , m k m_1,m_2,m_3,\cdots,m_k m1,m2,m3,,mk k k k个两两互素的正整数,则对于任意的 b 1 , b 2 , b 3 , ⋯   , b k b_1,b_2,b_3,\cdots,b_k b1,b2,b3,,bk,同余式组:
{ x ≡ b 1 m o d    m 1 x ≡ b 2 m o d    m 2 x ≡ b 3 m o d    m 3 ⋮ x ≡ b k m o d    m k \begin{aligned} \left\{ \begin{array}{lr} x\equiv b_1 \mod m_1 \\ x\equiv b_2 \mod m_2\\ x\equiv b_3 \mod m_3\\ \vdots\\ x\equiv b_k \mod m_k \end{array} \right. \end{aligned} xb1modm1xb2modm2xb3modm3xbkmodmk

有且仅有一个解,为:
x ′ ≡ b 1 ⋅ M 1 ′ ⋅ M + b 2 ⋅ M 2 ′ ⋅ M 2 + ⋯ + b k ⋅ M k ′ ⋅ M k m o d    m x^\prime \equiv b_1 \cdot M_1^\prime \cdot M+b_2 \cdot M_2^\prime \cdot M_2 + \cdots + b_k \cdot M_k^\prime \cdot M_k \mod m xb1M1M+b2M2M2++bkMkMkmodm
其中 M i = ∏ j = 1 k m j ( j ≠ i ) , M i ′ ⋅ M i ≡ 1 m o d    m i M_i=\prod \limits_{j=1}^{k} m_j(j\neq i), M_i^\prime \cdot M_i \equiv 1 \mod m_i Mi=j=1kmj(j=i),MiMi1modmi.
对于任意一个同余式 x ≡ b i m o d    m i x \equiv b_i \mod m_i xbimodmi,我们知道,对于 M j ( j ≠ i ) M_j(j \neq i) Mj(j=i) m i m_i mi的倍数,所以, b j ⋅ M j ′ ⋅ M j ≡ 0 m o d    m i . b_j \cdot M_j^\prime \cdot M_j \equiv 0 \mod m_i. bjMjMj0modmi.
x ′ ≡ b 1 ⋅ M 1 ′ ⋅ M 1 + b 2 ⋅ M 2 ′ ⋅ M 2 + ⋯ + b k ⋅ M k ′ ⋅ M k m o d    m ≡ b i ⋅ M i ′ ⋅ M i m o d    m i ≡ b i m o d    m i \begin{aligned} x^\prime &\equiv b_1 \cdot M_1^\prime \cdot M_1 +b_2 \cdot M_2^\prime \cdot M_2 +\cdots +b_k \cdot M_k^\prime \cdot M_k \mod m\\ &\equiv b_i \cdot M_i^\prime \cdot M_i \mod m_i\\ &\equiv b_i \mod m_i \end{aligned} xb1M1M1+b2M2M2++bkMkMkmodmbiMiMimodmibimodmi
这说明 x ′ x^\prime x的确是同余式组的解,显然,若 x ′ ′ x^{\prime \prime} x是同于式组的解,那么也必然满足上式,说明 x ′ ≡ x ′ ′ m o d    m x^\prime \equiv x^{\prime \prime} \mod m xxmodm,即同余式组的解式唯一的。

c++代码演示

#include<iostream>
#include<vector>
using namespace std;
//We need the extedned gcd algorithm to compute the inverse of M
vector<int> exgcd(int a,int b,int s1=1,int s2=0,int t1=0,int t2=1){
	int r=a%b;
	if(r==0){
		return {b,s2,t2};
	}
	int q=a/b;
	int s3=-q*s2+s1;
	int t3=-q*t2+t1;
	return exgcd(b,r,s2,s3,t2,t3);
}

//Warnning: the elements in vector ms must be coprime!
int crt(vector<int> ms,vector<int> bs){
	vector<int> Ms(ms.size());
	vector<int> Ms_prime(ms.size());
	int m=1;
	for(auto i:ms){
		m=m*i;
	}
	for(int i=0;i<ms.size();i++){
		Ms[i]=m/ms[i];
		auto temp=exgcd(Ms[i],ms[i]);
		Ms_prime[i]=temp[1];
		cout<<temp[1]<<endl;
	}
	int res=0;
	for(int i=0;i<ms.size();i++){
		res+=bs[i]*Ms[i]*Ms_prime[i]%m;
	}
	return res;
}

int main(){
	vector<int> ms={3,5,7};
	vector<int> bs={2,4,6};
	int res=crt(ms,bs);
	cout<<res<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值