hdu 1576扩展欧几里得算法

#include<stdio.h>
#define ll long long
/* 2.那么x,y的一组解就是x1*m1,y1*m1,但是由于满足方程的解无穷多个,
在实际的解题中一般都会去求解x或是y的最小正数的值。
以求x为例,又该如何求解呢?还是从方程入手,
现在的x,y已经满足a*x+b*y=m,那么a*(x+n*b)+b*(y-n*a)=m显然也是成立的。
可以得出x+n*b(n=…,-2,-1,0,1,2,…)就是方程的所有x解的集合,
由于每一个x都肯定有一个y和其对应,所以在求解x的时候可以不考虑y的取值。
取k使得x+k*b>0,x的最小正数值就应该是(x+k*b)%b,但是这个值真的是最小的吗??
如果我们将方程最有两边同时除以gcd(a,b),则方程变为a1*x+b1*y=m1,
同上面的分析可知,此时的最小值应该为(x+k*b1)%b1,由于b1<=b,所以这个值一定会小于等于之前的值。
在实际的求解过程中一般都是用while(x<0)x+=b1来使得为正的条件满足,为了更快的退出循环,
可以将b1改为b(b是b1的倍数),并将b乘以一个倍数后再加到x上。*/
ll x,y,q;
void extgcd(ll a,ll b) {
if(b==0) {
    x=1;y=0;q=a;
    return ;
}
extgcd(b,a%b);
ll temp=x;
x=y;y=temp-a/b*y;
return ;
}
int main() {
  ll n,t,b,k;
  scanf("%I64d",&t);
  while(t--) {
    scanf("%I64d%I64d",&n,&b);
    extgcd(b,9973);
    x=x*n/q;//
    k=9973/q;//
    x=(x%k+k)%k;//求最小的x
    printf("%I64d\n",x%9973);
  }
return 0;
}

posted @ 2014-07-07 17:20  HYDhyd  阅读(156)  评论(0编辑  收藏  举报