(扩展)中国剩余定理
对于一组同余方程
(xequiv a_1(mod quad n_1))
(xequiv a_2(mod quad n_2))
(xequiv a_3(mod n_3))
(xequiv a_n(mod n_m))
对于第一个和第二个式子
则有:
(x = a1 + k1*n1)
(x = a2 + k2*n2)
就有:
(a1 + k1 * n1 = a2 + k2 * n2)
(k1 * n1 - k2 * n2 = a2 - a1)
故我们设 (d = a_2 - a_1) 再变化一下形式就有:
(k_1 * n_1 + (-k_2) * n_2 = d)
令 (g = gcd(n_1,n_2))
这样我们就可以通过exgcd来求出一组解 x1,y1
满足 (x_1 * n_1 + y_2 * n_2 = g)
故: (x_1∗d/g∗n_1+y_2∗d/g∗n_2=g∗d/g)
则: (k1=x1∗d/g,k2=y1∗d/g)
从而得到一组通解
(k1=k1+n2/g∗T)
(k2=k2−n1/g∗T)
要使所求得的解最小且为正整数则可以根据 k1 的通解形式求得
(k_1 = ( k_1 % ( n_2/g ) + n_2/g ) % ( n_2/g ))
再带入 $x=a_1+k_1∗n_1 $得到 xx
令 A 为合并后的 a , N 为合并后的 n
**所以(N=lcm(n_1,n_2)=n_1∗n_2/g)
(x==k_1*p_1+a_1 (mod lcm(n_1,n_2));)
void exgcd(ll a,ll b,ll &g,ll &x,ll &y)
{
if (b == 0)
{
g = a;x = 1; y = 0;
return;
}
exgcd(b,a%b,g,y,x);
y-=(a/b)*x;
}
bool flag = false;
ll a1,a2,n1,n2;
ll abs(ll x) {return x>0?x:-x;}
void china()
{
ll d = a2 - a1;
ll g,x,y;
exgcd(n1,n2,g,x,y);
if (d % g == 0)
{
x = ((x*d/g)%(n2/g)+(n2/g))%(n2/g);
a1 = x*n1 + a1;
n1 = (n1*n2)/g;
}
else flag = true;
}
int n;
long long as[100001];
long long ps[100001];
ll exchina()
{
a1 = as[0];
n1 =ps[0];
for (ll i = 1;i<n;i++)
{
a2 = as[i];
n2 = ps[i];
china();
if (flag)
return -1;
}
return a1;
}
int main()
{
cin>>n;
flag = false;
for (ll i = 0;i<n;i++)
cin>>ps[i]>>as[i];
cout<<(long long)realchina()<<endl;
}