POJ 2891 Strange Way to Express Integers (中国剩余定理)

Strange Way to Express Integers
Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 9481   Accepted: 2877

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 a1a2…, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1a2, …, ak are properly chosen, m can be determined, then the pairs (airi) 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 airi (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



题目大意:

给定k个二元组(mi,ri)(1<=i<=k),表示x对mi模运算的余数为ri,然后据此求解最小的正整数N。

解题思路:

相关知识普及:

拓展欧几里德的上一篇文章已经介绍其原理:http://blog.csdn.net/a1061747415/article/details/26744509,现在补充其性质:

欧几里德求的问题是 ax+by=gcd(a,b)的解,那么对于通式 ax+by=c 是否有解呢? YES OR NO ?

答案是不一定,为什么这么说?

首先,ax1+by1=gcd(a,b) 对应 x1,y1一定有解,这个不用解释了吧

 然后,ap+bq=c 如果有解为p,q和x1,y1有什么关系呢?姐妹关系?朋友关系?NO

 因为 gcd(a,b)*   (   c  / gcd(a,b)   ) = c ,所以 x1*  (   c  / gcd(a,b)   ) = p,y1*  (   c  / gcd(a,b)   ) = q。

 呵呵,这个想法是不错,但是,对吗?很明显答案是对的,当且仅当  c % gcd(a,b) = 0 成立。

对于这道题:

因为 N%m1=r1 ,N%m2=r2,所以 m1*x+m2*y=r2-r1,这个知道吧?

然后,可以求出 方程 m1*x+m2*y=gcd(m1,m2) 的解为x0,y0,设d=gcd(m1,m2) ,

则m1*x+m2*y=r2-r1的解为 x=x0*(r2-r1)/g ,y=y0*(r2-r1)/g,

所以,这个方程的通解 m1*x+r1 + m1*m2/d ,也就是 其中一个解加上求余为0的部分;

注意:

1、这题要用long long 

2、m1*x也是 (m2/d)的倍数,因此,x要对(m2/d)求余,防止超过


解题代码:

#include <iostream>
#include <cstdio>
using namespace std;

typedef long long ll;

int n;

ll x,y;
ll extend_gcd(ll a,ll b){
    if(b==0){
        x=1;y=0;
        return a;
    }else{
        ll ans=extend_gcd(b,a%b);
        ll tmp=y;
        y=x-a/b*y;
        x=tmp;
        return ans;
    }
}

void solve(){
    ll m1,m2,r1,r2;
    scanf("%lld%lld",&m1,&r1);
    bool flag=true;
    for(int i=1;i<n;i++){
        scanf("%lld%lld",&m2,&r2);
        ll d=extend_gcd(m1,m2);
        ll mod=m2/d;
        if((r2-r1)%d!=0){
            flag=false;
            continue;
        }
        x=(r2-r1)/d*x % mod;
        r1=m1*x+r1;
        m1=m2*m1/d;
    }
    if(!flag) printf("-1\n");
    else cout<<(r1%m1+m1)%m1<<endl;
}

int main(){
    while(scanf("%d",&n)!=EOF){
        solve();
    }
    return 0;
}


posted @ 2014-06-16 19:49  炒饭君  阅读(134)  评论(0编辑  收藏  举报