Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as following:
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?
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.
All integers in the input and the output are non-negative and can be represented by 64-bit integral types.
题意:给出k组ai与ri,求满足任意组的 m%ai=ri的m的最小正整数,若不存在输出-1.
题解:额,智商捉鸡(⊙o⊙)… 断断续续看了一天,翻了好几本书,才有点小眉头,终于把书上那些定理证出来了,不过估计很快又会忘了/(ㄒoㄒ)/~~
这里给出了 m mod(ai)=ri ,那么得到 ai*k+ri=m ,两边同时 mod (ai)得到 ri mod(ai) ≡ m。 这里给出了k组ai 与 ri,那么我们连立k组 ri mod (ai) ≡ m ,求解即可。 得到 :
对于 x≡r1(mod a1)
x≡r2(mod a2)
相当于解不定方程:x*a1+y*a2=r2-r1
代码如下:
#include
#include
#include
using namespace std;
#define LL long long
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(!b)
{
x=1; y=0;
d=a;
}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main()
{
LL a1,a2,r1,r2,i,n;
while(scanf("%lld",&n)!=EOF)
{
int flag=1;
scanf("%lld%lld",&a1,&r1);
for(i=1;i {
scanf("%lld%lld",&a2,&r2);
LL a=a1,b=a2,d,c=r2-r1,x0,y0;
exgcd(a,b,d,x0,y0);
if(c%d!=0)
flag=0;
LL s=b/d;
x0=(x0*(c/d)%s+s)%s;//a*x+b*y==c的最小整数解
r1=r1+a1*x0;//迭代r1的值
a1=a1*(a2/d);//取a1和a2的公倍数
}
if(!flag)
printf("-1\n");
else
printf("%I64d\n",r1);
}
return 0;
}