中国剩余定理(CRT):
若 m1, m2,...,mk 两两互质,则同余方程组
x≡a1 (mod m1)
x≡a2 (mod m2)
…………………
x≡ak (mod mk)
有整数解,解为
其中:
long long CRT(long long a[], long long m[], int n)
{
long long M = 1;
for(long long i = 0; i < n; i ++)
{
M *= m[i];
}
long long ans = 0;
for(long long i = 0; i < n; i ++)
{
long long tm = M/m[i];
long long x = inv(tm,m[i]);
ans = (ans+tm*x*a[i])%M;
}
return (ans + M)%M;
}
扩展中国剩余定理(EX_CRT):
其中 m1, m2 , m3 ..... mk,不是两两互质的
当只有一个方程式时:解为
假设已经求出的前k-1个方程式的解为
则加入第k个式子后,
转化一下
用扩展欧几里得求出t 和 gcd,若 ,不满足扩展欧几里得方程条件,则方程无解
否则,解为
#include<bits/stdc++.h>
using namespace std;
long long a[121000], m[120000];
long long ex_gcd(long long a, long long b, long long &x, long long &y)//扩展欧几里得
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
else
{
long long gcd = ex_gcd(b,a%b,x,y);
long long x1 = y;
long long y1 = x-a/b*y;
x = x1;
y = y1;
return gcd;
}
}
long long mul(long long a,long long b,long long mod)//快速乘,取模
{
long long res=0;
while(b>0)
{
if(b&1)
res=(res+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return res;
}
long long ex_crt(long long ai[], long long mi[], long long n)
{
long long x,y;
long long M=mi[1],ans=ai[1];
for(int i=2; i<=n; i++)
{
long long a=M,b=mi[i],c=(ai[i]-ans%b+b)%b;
long long gcd=ex_gcd(a,b,x,y),bg=b/gcd;
if(c%gcd!=0)
return -1;
x=mul(x,c/gcd,bg);
ans+=x*M;
M*=bg;
ans=(ans%M+M)%M;
}
return (ans%M+M)%M;
}
int main()
{
long long n;
scanf("%lld",&n);
for(int i = 1; i <= n; i ++)
{
scanf("%lld %lld",&m[i], &a[i]);
}
printf("%lld\n",ex_crt(a,m,n));
return 0;
}