【poj2891-Strange Way to Express Integers】拓展欧几里得-同余方程组

时间:2023-12-11 16:24:32

http://poj.org/problem?id=2891

题意:与中国剩余定理不同,p%ai=bi,此处的ai(i=1 2 3 ……)是不一定互质的,所以要用到的是同余方程组,在网上看到有人称为拓展中国剩余定理。

具体讲解可以看我昨天的博文:http://www.cnblogs.com/KonjakJuruo/p/5176417.html

//poj2891
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; typedef long long LL;
const LL N=;
LL a[N],b[N];
LL tx,ty; LL exgcd(LL aa,LL bb)
{
if(bb==) {tx=,ty=;return aa;}
LL d=exgcd(bb,aa%bb);
LL x=ty,y=tx-(aa/bb)*ty;
tx=x;ty=y;
return d;
} LL lcu(LL aa,LL bb)
{
LL d=exgcd(aa,bb);
return aa*bb/d;
} int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
// printf("%d\n",(-5)%3);
LL n,a1,b1,x;
while(scanf("%I64d",&n)!=EOF)
{
bool bk=;
for(LL i=;i<=n;i++)
scanf("%I64d%I64d",&a[i],&b[i]);
LL A=a[],B=a[],C=b[]-b[];
LL g=exgcd(A,B);
if(C%g) bk=;
else {
x=((tx*C/g)%(B/g)+(B/g))%(B/g);
b1=a[]*x+b[];
a1=lcu(a[],a[]);
}
for(LL i=;i<=n;i++)
{
A=a1,B=a[i],C=b[i]-b1;
g=exgcd(A,B);
if(C%g) {bk=;break;}
x=((tx*C/g)%(B/g)+(B/g))%(B/g);
b1=a1*x+b1;
a1=lcu(a1,a[i]);
}
if(bk) printf("%I64d\n",b1);
else printf("-1\n");
}
return ;
}