求M = 所有m之积 然后Mi = M / mi
找到x **使得x mod mi = ai**成立
对于每两个式子 都可以推出①式
即 用扩展欧几里得算法 可以算出k1,-k2和m2–m1
判无解 : 若**(m2–m1) % d != 0** 说明该等式无解 即原方程无解 本题无解
找到最小正整数解
等效替代
设a0 = gcd(a1,a2) , m0 = k1 * a1 + m1 得到新的式子和原方程长得一模一样
也就是说 每两个式子 都可以通过合并的方式 写成一个式子
只要将所有n个式子全都合并成一个式子 x = k*a + m 就可以求解x了
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
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()
{
int n;
cin>>n;
LL x=0,m1,a1;
cin>>a1>>m1;
for(int i=0;i<n-1;i++){ //输入n-1次
LL m2,a2;
cin>>a2>>m2;
LL k1,k2;
LL d=exgcd(a1, a2,k1,k2);
if((m2-m1) % d) //无解
{
x = -1;
break;
}
k1 *= (m2-m1) / d; //k1乘相应系数
k1 = (k1 %(a2/d) + a2 / d) % (a2/d); //见下方注释
x = k1 * a1 + m1; //根据公式③
//更新a1 m1 进行下一次合并
m1 = k1 * a1 + m1;
a1 = abs(a1 * a2 /d);
}
if(x!=-1) x=(m1%a1+a1)%a1; //若x为负数 将x变成正数
cout<<x<<endl;
return 0;
}
参考题解 :https://www.acwing.com/solution/content/3539/