Description
Choose k different positive integers a1, a2, …, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1, a2, …, ak are properly chosen, m can be determined, then the pairs (ai, ri) can be used to express m.
“It is easy to calculate the pairs from m, ” said Elina. “But how can I find m from the pairs?”
Since Elina is new to programming, this problem is too difficult for her. Can you help her?
Input
The input contains multiple test cases. Each test cases consists of some lines.
- Line 1: Contains the integer k.
- Lines 2 ~ k + 1: Each contains a pair of integers ai, ri (1 ≤ i ≤ k).
Output
Output the non-negative integer m on a separate line for each test case. If there are multiple possible values, output the smallest one. If there are no possible values, output -1.
Sample Input
2 8 7 11 9
Sample Output
31这道题的题意就是让你求同余方程的解,但是有一点不一样的是 他给的余数并不是互素的。
这里需要一个个的合并一下
x=a1+m1x1
x=a2+m2x2
所以 a1+m1x1=a2+m2x2 转移一下 m1x1-m2x2=a2-a1
用扩展欧几里得算出x1的最小整数解 带入到x=a1+m1x1
等到x后合并为一个方程
y三x(mod lcm(m1,m2))
AC代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
typedef long long LL;
const int maxn=1005;
ll m[maxn],a[maxn],s[maxn];
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
void extend_Euclid(ll a, ll b, ll &x, ll &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
extend_Euclid(b, a % b, x, y);
ll tmp = x;
x = y;
y = tmp - (a / b) * y;
}
ll Inv(ll a,ll b){
ll d = gcd(a, b);
if(d != 1) return -1;
ll x,y;
extend_Euclid(a, b, x, y);
return (x % b+ b) % b;
}
bool merge(ll a1,ll m1,ll a2,ll m2,ll &a3,ll &m3){
ll d=gcd(m1,m2);
ll c=a2-a1;
if(c%d) return false;
c=(c%m2+m2)%m2;
m1/=d;
m2/=d;
c/=d;
c*=Inv(m1,m2);
c%=m2;
c*=m1*d;
c+=a1;
m3=m1*m2*d;
a3=(c%m3+m3)%m3;
return true;
}
ll CRT(ll a[],ll m[],int n){
ll a1=a[1];
ll m1=m[1];
for(int i=2;i<=n;i++){
ll a2=a[i];
ll m2=m[i];
ll m3,a3;
if(!merge(a1,m1,a2,m2,a3,m3))
return -1;
a1=a3;
m1=m3;
}
return (a1%m1+m1)%m1;
}
int main()
{
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%lld%lld",&m[i],&a[i]);
}
cout<<CRT(a,m,n)<<endl;
}
}