您的位置:首页 > 其它

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

2016-08-04 16:58 375 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ 数论
相关文章推荐