POJ 2891 Strange Way to Express Integers

来源:互联网 发布:淘宝千人千面刷单 编辑:程序博客网 时间:2024/05/21 06:26

扩展欧几里德第二题~

这个题真是搞了好长时间才懂啊~~


题目大意:

 有一个数mod ri 等于ai  ,求这个数,若求不出来输出“-1”。


解题思路:

对于 x=r1(mod a1)
         x=r2(mod a2)

相当于解不定方程:x*a1+y*a2=r2-r1

先求解方程:x*a1+y*a2=r2-r1=gcd(a1,a2)

得出解x,则方程x*a1+y*a2=r2-r1的解x0=x*(r2-r1)/gcd(a1,a2)=x*c/d

令s=a2/d,那么x0的最小解为:x0=(x0%s+s)%s即可得出解x=r1+x0*a1
然后将x赋值给r1,lcm(a1,a2)赋值给a1,继续求解。直到最后


下面是代码:

[cpp] view plain copy
  1. #include <set>  
  2. #include <map>  
  3. #include <queue>  
  4. #include <math.h>  
  5. #include <vector>  
  6. #include <string>  
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <stdlib.h>  
  10. #include <iostream>  
  11. #include <algorithm>  
  12.   
  13. #define eps 1e-6  
  14. #define pi acos(-1.0)  
  15. #define inf 107374182  
  16. #define inf64 1152921504606846976  
  17. #define lc l,m,tr<<1  
  18. #define rc m + 1,r,tr<<1|1  
  19. #define iabs(x)  ((x) > 0 ? (x) : -(x))  
  20. #define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE))  
  21. #define clearall(A, X) memset(A, X, sizeof(A))  
  22. #define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE))  
  23. #define memcopyall(A, X) memcpy(A , X ,sizeof(X))  
  24. #define max( x, y )  ( ((x) > (y)) ? (x) : (y) )  
  25. #define min( x, y )  ( ((x) < (y)) ? (x) : (y) )  
  26.   
  27. using namespace std;  
  28.   
  29. long long exgcd(long long m,long long n,long long &x,long long &y)  
  30. {  
  31.     long long x1,y1,x0,y0;  
  32.     x0=1; y0=0;  
  33.     x1=0; y1=1;  
  34.     x=0; y=1;  
  35.     long long r=m%n;  
  36.     long long q=(m-r)/n;  
  37.     while(r)  
  38.     {  
  39.         x=x0-q*x1; y=y0-q*y1;  
  40.         x0=x1; y0=y1;  
  41.         x1=x; y1=y;  
  42.         m=n; n=r; r=m%n;  
  43.         q=(m-r)/n;  
  44.     }  
  45.     return n;  
  46. }  
  47.   
  48. int main()  
  49. {  
  50.     int n;  
  51.     long long a1,r1,a2,r2,c,d,x,y;  
  52.     bool flat;  
  53.     while(scanf("%d",&n)!=EOF)  
  54.     {  
  55.         flat=false;  
  56.         scanf("%lld%lld",&a1,&r1);  
  57.         for(int i=1;i<n;i++)  
  58.         {  
  59.             scanf("%lld%lld",&a2,&r2);  
  60.             if(flat)continue;  
  61.             c=r2-r1;  
  62.             d=exgcd(a1,a2,x,y);  
  63.             if(c%d)  
  64.             {  
  65.                 flat=true;  
  66.                 continue;  
  67.             }  
  68.             x*=c/d;  
  69.             a2/=d;  
  70.             x=(x%a2+a2)%a2;  
  71.             r1=r1+x*a1;  
  72.             a1*=a2;  
  73.         }  
  74.         if(flat)puts("-1");  
  75.         else printf("%lld\n",r1);  
  76.     }  
  77.     return 0;  
  78. }