Strange Way to Express Integers(유클리드+곱셈 역 원 확장+중국 잉여 정리 구 해 비 상호 적 인 모 선형 방정식 그룹)

6191 단어 ACMpoj수론
Link:http://poj.org/problem?id=2891
Strange Way to Express Integers
Time Limit: 1000MS
 
Memory Limit: 131072K
Total Submissions: 11454
 
Accepted: 3549
Description
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?
Input
The input contains multiple test cases. Each test cases consists of some lines.
  • Line 1: Contains the integer k.
  • Lines 2 ~ k + 1: Each contains a pair of integers ai, ri (1 ≤ i ≤ k).

  • Output
    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.
    Sample Input
    2
    8 7
    11 9
    Sample Output
    31
    Hint
    All integers in the input and the output are non-negative and can be represented by 64-bit integral types.
    Source
    POJ Monthly--2006.07.30, Static
    제목:모 선형 방정식 그룹의 각 식 의 제수 와 여 수 를 제시 하고 이 식 의 피제수 가 얼마 인지 최소 로 만족 시 키 도록 한다.풀 리 지 않 으 면 출력-1.
    프로 그래 밍 사상:유클리드+곱셈 역 원+중국 잉여 정리 확장.
    AC code 1(재 귀적 판):
    /** 
          (   ) 
    */  
    #include   
    #include   
    #include   
    using namespace std;  
    typedef __int64 int64;  
    int64 Mod;  
      
    int64 gcd(int64 a, int64 b)  
    {  
        if(b==0)  
            return a;  
        return gcd(b,a%b);  
    }  
      
    int64 Extend_Euclid(int64 a, int64 b, int64&x, int64& y)//ax+by=gcd(a,b)  
    {  
        if(b==0)  
        {  
            x=1,y=0;  
            return a;  
        }  
        int64 d = Extend_Euclid(b,a%b,x,y);  
        int64 t = x;  
        x = y;  
        y = t - a/b*y;  
        return d;  
    }  
      
    //a  n      ,     -1  
    int64 inv(int64 a, int64 n)  
    {  
        int64 x,y;  
        int64 t = Extend_Euclid(a,n,x,y);  
        if(t != 1)  
            return -1;  
        return (x%n+n)%n;  
    }  
      
    //            
    bool merge(int64 a1, int64 n1, int64 a2, int64 n2, int64& a3, int64& n3)  
    {  
        int64 d = gcd(n1,n2);  
        int64 c = a2-a1;  
        if(c%d)  
            return false;  
        c = (c%n2+n2)%n2;  
        c /= d;  
        n1 /= d;  
        n2 /= d;  
        c *= inv(n1,n2);  
        c %= n2;  
        c *= n1*d;  
        c += a1;  
        n3 = n1*n2*d;  
        a3 = (c%n3+n3)%n3;  
        return true;  
    }  
      
    //       x=ai(mod ni),ni       
    int64 China_Reminder2(int len, int64* a, int64* n)//len         ,a[i]、n[i]     i      、    
    {  
        int64 a1=a[0],n1=n[0];  
        int64 a2,n2;  
        for(int i = 1; i < len; i++)  
        {  
            int64 aa,nn;  
            a2 = a[i],n2=n[i];  
            if(!merge(a1,n1,a2,n2,aa,nn))  
                return -1;//    -1  
            a1 = aa;  
            n1 = nn;  
        }  
        Mod = n1;  
        return (a1%n1+n1)%n1;  
    }  
    int64 a[1000],b[1000];  
    int main()  
    {  
        int i;  
        int k;  
        while(scanf("%d",&k)!=EOF)  
        {  
            for(i = 0; i < k; i++)  
                scanf("%I64d %I64d",&a[i],&b[i]);  
            printf("%I64d
    ",China_Reminder2(k,b,a)); } return 0; }

    AC code 2(비 귀속 판):
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define PI acos(-1.0)
    #define LINF 1000000000000000000LL
    #define eps 1e-8
    #define LL long long
    #define MAXN 100010 
    #define MOD 1000000007
    using namespace std;
    const int INF=0x3f3f3f3f;
    LL Mod;  
    LL gcd(LL a, LL b)  
    {  
        if(b==0)  
            return a;  
        return gcd(b,a%b);  
    }  
    LL exgcd(LL A,LL &x,LL B,LL &y)
    {
        LL x1,y1,x0,y0;
        x0=1;y0=0;
        x1=0;y1=1;
        LL r=(A%B+B)%B;
        LL q=(A-r)/B;
        x=0;y=1;
        while(r)
        {
            x=x0-q*x1;
            y=y0-q*y1;
            x0=x1;
            y0=y1;
            x1=x;y1=y;
            A=B;B=r;r=A%B;
            q=(A-r)/B;
        }
        return B;
    }
    LL ABS(LL x)
    {
    	return x>=0?x:-x;
    }
    /*         :
     m≥1,gcd(a,m)=1,   c   ca≡1(mod m)    c   a  m  ,   a-1(mod m) a-1             a-1
      :  (a/b)%c , a          ((a%c)*((b-1)%c))%c,  :  (b-1) b%c     ,  b  1!!! 
                      :*/
    //a  n      ,     -1(a * b % n == 1,  a,n, b   a n     )    
    LL inv(LL a, LL n)  
    {  
        LL x,y;  
        //int64 t = Extend_Euclid(a,n,x,y); 
    	/*******************************************
    	             
    	  :exgcd(a,x,b,y);
    	 :  x a b     ,y b a     
    	********************************************/ 
        LL t = exgcd(a,x,n,y);  
        if(t != 1)  
            return -1;  
        return (x%n+n)%n;  
    }  
      
    //            
    bool merge(LL a1, LL n1, LL a2, LL n2, LL& a3, LL& n3)  
    {  
        LL d = gcd(n1,n2);  
        LL c = a2-a1;  
        if(c%d)  
            return false;  
        c = (c%n2+n2)%n2;  
        c /= d;  
        n1 /= d;  
        n2 /= d;  
        c *= inv(n1,n2);  
        c %= n2;  
        c *= n1*d;  
        c += a1;  
        n3 = n1*n2*d;  
        a3 = (c%n3+n3)%n3;  
        return true;  
    }  
      
    //       x=ai(mod ni),ni       
    LL China_Reminder2(LL len, LL* a, LL* n)//len         ,a[i]、n[i]     i      、    
    {  
        LL a1=a[0],n1=n[0];  
        LL a2,n2;  
        for(int i = 1; i < len; i++)  
        {  
            LL aa,nn;  
            a2 = a[i],n2=n[i];  
            if(!merge(a1,n1,a2,n2,aa,nn))  
                return -1;//    -1  
            a1 = aa;  
            n1 = nn;  
        }  
        Mod = n1;  
        return (a1%n1+n1)%n1;  
    }  
    LL a[1000],b[1000];  
    int main()  
    {  
        int i;  
        int k;  
        while(scanf("%d",&k)!=EOF)  
        {  
            for(i = 0; i < k; i++)  
                scanf("%I64d %I64d",&a[i],&b[i]);  
            printf("%I64d
    ",China_Reminder2(k,b,a)); } return 0; }

    좋은 웹페이지 즐겨찾기