poj2891 拓展欧几里得

时间:2023-03-08 23:57:12
poj2891 拓展欧几里得
 //Accepted    164 KB    16 ms
 //拓展欧几里得
 //m=a1*x+b1  --(1)
 //m=a2*(-y)+b2 --(2)
 //->a1*x+a2*y=b2-b1
 //由欧几里得算法可得上式的解
 //由a*x+b*y=gcd(a,b)
 //可得a(x+b)+b(y-a)=gcd(a,b)
 //所以最小正整数解x=(x%b+b)%b;
 //现考虑由(1)(2)两式得到的解m
 //有x=m mod (a1*a2/gcd(a1,a2))
 //m是最小正整数解,m+a1*a2/gcd(a1,a2)也是(1)(2)的解
 #include <cstdio>
 #include <cstring>
 #include <iostream>
 using namespace std;
 __int64 extend_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
 {
     )
     {
         x=;
         y=;
         return a;
     }
     __int64 r=extend_gcd(b,a%b,x,y);
     __int64 t=x;
     x=y;
     y=t-a/b*y;
     return r;
 }
 int main()
 {
     int n;
     while (scanf("%d",&n)!=EOF)
     {;
     __int64 a1,b1,a2,b2;
     __int64 x,y,c,d;
     scanf("%I64d%I64d",&a1,&b1);
     ;i<=n;i++)
     {
         scanf("%I64d%I64d",&a2,&b2);
         if (flag) continue;
         d=extend_gcd(a1,a2,x,y);
         c=b2-b1;
         if (c%d)
         {
             flag=;
         }
         else
         {
             __int64 p=a2/d;
             x=(c/d*x%p+p)%p;
             b1=a1*x+b1;
             a1=a1/d*a2;
         }
     }
     if (flag) printf("-1\n");
     else printf("%I64d\n",b1);
     }
     ;
 }