#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
扩展欧几里得
求出A,B的最大公约数,且求出X,Y满足AX + BY = GCD(A,B)
复杂度:O(logN)
=========================================*/
ll extend_gcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
else {
ll r = extend_gcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
}
中国剩余定理(两两互质)a[i]之间两两互质
复杂度: O(NlogN)
输入a,m 第i个方程表示为x ≡ ai(mod mi)
n 表示方程个数
=========================================*/
const int maxn = 20;
ll a[maxn], m[maxn], n;
ll CRT(ll a[], ll m[], int n) {
ll M = 1;
for (int i = 0; i < n; i++) M *= m[i];
ll ret = 0;
for (int i = 0; i < n; i++) {
ll x, y;
ll tm = M / m[i];
extend_gcd(tm, m[i], x, y);
ret = (ret + tm * x * a[i]) % M;
}
return (ret + M) % M;
}
中国剩余定理非互质版
输入a,m 第i个方程表示为x ≡ ai(mod mi)
如果有解返回解,无解返回-1
复杂度:O(NlogN)
=========================================*/
ll CRT2(ll a[], ll m[], int n) {
if (n == 1) {
if (m[0] > a[0]) return a[0];
else return -1;
}
ll x, y, d;
for (int i = 1; i < n; i++) {
if (m[i] <= a[i]) return -1;
d = extend_gcd(m[0], m[i], x, y);
if ((a[i] - a[0]) % d != 0) return -1;
ll t = m[i] / d;
x = ((a[i] - a[0]) / d * x % t + t) % t;
a[0] = x * m[0] + a[0];
m[0] = m[0] * m[i] / d;
a[0] = (a[0] % m[0] + m[0]) % m[0];
}
return a[0];
}
int main()
{
cout<<" X = a (mod m) "<<endl<<"puts the lenths of arry first"<<endl;
while (scanf("%I64d",&n),n)
{
for (int i=0;i<n;i++)
{
scanf("%I64d%I64d",&a[i],&m[i]);
}
printf("CRT = %I64d \n",CRT(a,m,n));
printf("CRT2 = %I64d \n",CRT2(a,m,n));
}
return 0;
}