1.自然语言描述
中国剩余定理:对于有k个线性同余方程(x≡ai(mod mi),mi之间两两互质)组成的线性同余方程组,通过以下步骤求解:
1.求出所有模数m的乘积记作M;
2.对于第i个线性同余方程:①令ni=M/mi;②求出ni在mod mi意义下的逆元ni^(-1);③令ci=nini ^(-1);
3.方程组的唯一解为∑(i=1,k)aici(mod mi)
中国剩余定理有严格的条件限制,即模数之间两两互质。
一般的线性同余方程组,将两个方程合并为一个,合并k-1次,最终得到一个线性同余方程。
2.代码描述
题目:Acwing.204 表达整数的奇怪方式题目链接
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
int n;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b){
x=1,y=0;
return a;
}
LL d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main(void)
{
scanf("%d",&n);
bool flag=true;
LL a1,m1;
scanf("%lld%lld",&a1,&m1);
for(int i=0;i<n-1;i++){
LL a2,m2;
scanf("%lld%lld",&a2,&m2);
LL k1,k2;
LL d=exgcd(a1,a2,k1,k2);
if((m2-m1)%d){
flag=false;
break;
}
k1*=(m2-m1)/d;
LL t=a2/d;
k1=(k1%t+t)%t;//可得到方程的最小整数解
m1=k1*a1+m1;
a1=abs(a1/d*a2);
}
if(flag)
printf("%lld\n",(LL)(m1%a1+a1)%a1);
else
printf("-1\n");
return 0;
}