POJ-2891 Strange Way to Express Integers (数论:扩展欧几米德定理)

来源:互联网 发布:轻而易举瓷砖软件 编辑:程序博客网 时间:2024/06/16 17:24

POJ-2891 Strange Way to Express Integers(扩展欧几米德定理)

题目链接:http://poj.org/problem?id=2891

题意: 已知 k组数据ai,ri,求满足 x≡ri(mod ai)的最小值x min

    /*    思路:         因不互质,两两相处理          k1*a1 + r1 = x         k2*a2 + r2 = x         k1*a1 + k2*a2= gcd(a1,a2) = r2-r1         k1*a1 %a2 = (r2-r1) %a2  ,若此式成立即 (r2-r1) 为 gcd(a1,a2) 的倍数          求出k1代入原式求k1min,再代入求x         更新a1为两者的最小公倍数,r1为x        */#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;typedef long long LL;LL n,m,k,t;LL z,x,y,a,b;LL ex_gcd(LL a,LL b,LL &z,LL &y){    if(b==0){        z=1,y=0;        return a;    }else{        LL r = ex_gcd(b, a%b, y, z);        y -= a/b*z;        return r;    }}int main(){    LL a1,a2,r1,r2,k1;    int flag;    while(~scanf("%lld",&n)){        n--;        scanf("%lld %lld",&a1,&r1);         flag = 0;        while(n--){ //因不互质,两两相处理             scanf("%lld %lld",&a2,&r2);             LL gc = ex_gcd(a1, a2, z, y);//gcd(a1,a2),z*a1+ y*a2 = gcd(a1,a2)            if( (r2-r1)%gc) flag = 1;//满足(r2-r1) 为 gcd(a1,a2) 的倍数             k1 = (r2-r1)/gc*z;                 LL t = a2/gc;// a1 中没有 a2 的因子             k1 = ( k1%t + t ) % t;//使得k1能被t整除,且此时最小            x = r1 + k1*a1;//代入公式求 x             a1 = (a1*a2)/gc , r1 = x;        }        if(flag) printf("-1\n");        else printf("%lld\n",x);         }    return 0;}
0 0
原创粉丝点击