【题目描述】:
Elina正在读刘汝佳写的一本书,它介绍了一种表达非负整数的奇怪方法。方式如下:
选择k个不同的正整数a1,a2,…,ak。对于一些非负整数m,将它除以每个ai (1<=i<=k)可以得到余数ri。如果a1,a2,…,ak被适当地选择,m被确定,那么这些(ai,ri)对可以用来表示m。
Elina说:“通过m计算ri很容易。”“但是我怎么才能从这些(ai,ri)对中找到m呢?“
由于Elina对编程很陌生,这个问题对她来说太难了。你能帮助她吗?
【输入描述】:
第一行:一个整数k
以下k行:每行两个整数,表示ai和ri(1<=i<=k)。
【输出描述】:
输出一行,表示最小的非负整数m,如果没有解,输出-1。
【样例输入】:
2
8 7
11 9
【样例输出】:
31
【时间限制、数据范围及描述】:
时间:1s 空间:128M
2<=k<=10000;
注意:输入和输出中的所有整数都是非负的,可以用64位整型来表示。
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
using namespace std;
long long a[100055],r[100052],n;
long long extgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
long long d=extgcd(b,a%b,x,y);
long long t=x;
x=y;
y=t-a/b*y;
return d;
}
long long solve() {
long long d, c ,i, x, y, t;
for(i=1;i<n;i++) {
c = r[i] - r[i - 1];
d = extgcd(a[i - 1], a[i], x, y);
if(c % d != 0) return -1;
t = a[i] / d;
x = (x * (c / d) % t + t) % t;
r[i] = a[i - 1] * x + r[i - 1];
a[i] = a[i - 1] * (a[i] / d);
}
return r[n - 1];
}
int main(){
cin>>n;
for(long long i=0;i<n;i++)
{
scanf("%lld%lld",&a[i],&r[i]);
}
printf("%lld\n",solve());
}