POJ_2891_중국 잉여정리

5105 단어 POJ수론

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

문제풀이의 방향


중국 잉여정리: 어떤 문제를 풀 수 있을까요?질문:물건 한 무더기 3개, 3개, 2개 5개, 5개 3개, 7개, 7개 2개 남았는데 이 물건 몇 개냐고요?모형선형 방정식 그룹의 총 수가 n이면 n%3=2, n%5=3, n%7=2;
m%a1=r1; m%a2=r2; m%a3=r3;
m%an=rn; 그래서 m=k1*a1+r1;m=k2*a2+r2; =>k1*a1+r1=k2*a2+r2; =>k1*a1+k2*a2=r2-r1; =>a1*x+a2*y=c;(유클리드 확장) 먼저 c%gcd(a1,a2)를 통해 해가 존재하는지 확인하고 해가 존재하면 x를 구하면 m=a1*x+r1을 얻을 수 있다.풀다m을 하나의 특해로 하면 하나의 해계를 얻을 수 있다. M=m+k*lcm(a1,a2)(k는 임의의 정수);lcm(a,b)는 a,b의 최소 공배수,lcm(a,b)=a*b/gcd(a,b);M%lcm(a1,a2)=m로 변형;새로운 모듈 방정식을 얻어 A=lcm(a1,a2),R=m;M%A=R(m) 그래서 m%a1=r1;m%a2=r2;M%lcm(a1,a2)=m로 병합할 수 있음;이렇게 두 개를 합치면 반복해서 조작하면 최종 결과를 얻을 수 있다.코드 중 r1=x*a1+r1;a1=a1*a2/d; 즉 M%lcm(a1,a2)=m입니다.그래서 r1=m;a1=lcm(a1,a2)=a1*a2/gcd(a1,a2);

코드

#include 
#include 
using namespace std;
long long gcd(long long a,long long b,long long& x,long long& y )//      
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    else
    {
        long long d=gcd(b,a%b,y,x);
        y-=x*(a/b);
        return d;
    }
}
int main()
{
    int n;
    long long a1,a2,r1,r2,solve;
    long long c;
    long long x,y;
    //         n,                ,
    while(scanf("%d",&n)!=EOF)
    {
        solve=0;
        scanf("%lld%lld",&a1,&r1);
        for(int i=1;iscanf("%lld%lld",&a2,&r2);
            c=r2-r1;
            long long d=gcd(a1,a2,x,y);
            if(c%d!=0)
                solve=1;
            x=x*(c/d);
            x=(x%(a2/d)+(a2/d))%(a2/d);//     
            r1=x*a1+r1;//  r1,       m
            a1=a1*a2/d;//  a1
        }
        if(solve==1)
            printf("-1
"
); else printf("%lld
"
,r1); } return 0; }

좋은 웹페이지 즐겨찾기