中国剩余定理
一. 表达整数的奇怪方式
题目来源:表达整数的奇怪方式
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long LL;
int n;
int flog=1;//有解1,无解0
LL exgcd(LL a, LL b, LL &x, LL &y)
{
if(b == 0)
{
x = 1, y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
scanf("%d", &n);
LL a1, m1;
scanf("%lld%lld", &a1, &m1);
for(int i = 0; i < n-1; i++)
{
LL a2, m2, k1, k2; //k1,k2方程的解 x=k1a1+m1 x=k2a2+m2 -->k1a1-k2a2=m2-m1
scanf("%lld%lld", &a2, &m2);
LL d = exgcd(a1, a2, k1, k2);//gcd(a,b)
if((m2 - m1) % d!=0)
{
flog=0;
break;
}
else
{
// k1a1-k2a2=m2-m1
// 求得,特解 k1撇=k1*(m2-m1)/d
// 求得,通解 k1=k1撇+k*a2/d;
// 由于数据范围问题,k1解必须最小正整数,即k1=(k1%t+t)%t; t=abs(a2/d);
// 解k1带入,循环
k1=k1*(m2-m1)/d;//特解扩大
LL t=a2/d;
k1=(k1%t+t)%t;//此时k1解最小
m1=a1*k1+m1;
a1 = abs(a1 * a2 / d) ;
}
}
if(flog==0)puts("-1");
else printf("%lld\n", m1);
return 0;
}