http://acm.hdu.edu.cn/showproblem.php?pid=2669

扩展欧几里德。

扩展欧几里德: 给一个线性方程X*a+Y*b=m,给出a,b,m让求解X和Y。

首先,只有m%gcd(a,b)==0 时 该线性方程才有解。

假使a=k1 *gcd(a,b),b=k2 * gcd(a,b);

那么方程左边就等于(X*k1+Y*k2)*gcd(a,b),所以仅当m能被gcd(a,b)整除时方程才有解。

为了求上述方程的解,我们不妨先来求方程a*X+b*Y=gcd(a,b)的解,设d=m/gcd(a,b);

所以a*(d*X)+b*(d*y)=d*gcd(a,b)=m,求出这个方程的解原方程的解也就求出了。

根据欧几里德有gcd(a,b)=gcd(b,a%b)

所以a*X+b*Y=gcd(a,b)=gcd(b,a%b)=b*X1+(a%b)*Y1;

令k=a/b , r=a%b

a=b*k+r;

得出X=Y1 ,  Y=X1-Y1*(a/b);

__int64 X,Y; //全局变量

void extend_GCD(__int64 a,__int64 b)
{

    __int64
X1,Y1;
    if
(b==0)
    {

        X=1;
        Y=0;
        return
;
    }

    extend_GCD(b,a%b);
    X1=Y;
    Y1=X-Y*(a/b);
    X=X1;
    Y=Y1;
}

这样X*d,Y*d就是原方程的一组解。

满足方程的解有无数多个,a*(X + n*b) + b*(Y - n*a)=m; n=(...-2,-1,0,1,2...);

一般是让求最小的X并且X>=0,我们只需找X,每一个X都对应唯一的一个Y.

X所以最后的解为X%b,如果为负数就再加b

View Code
 1 # include<stdio.h>
 2 # include<string.h>
 3 # include<stdlib.h>
 4 __int64 X,Y;
 5 __int64 gcd(__int64 a,__int64 b)
 6 {
 7     __int64 tmp;
 8     while(a%b)
 9     {
10         tmp=a%b;
11         a=b;
12         b=tmp;
13     }
14     return b;
15 }
16 void extend_GCD(__int64 a,__int64 b)
17 {
18     __int64 X1,Y1;
19     if(b==0)
20     {
21         X=1;
22         Y=0;
23         return;
24     }
25     extend_GCD(b,a%b);
26     X1=Y;
27     Y1=X-Y*(a/b);
28     X=X1;
29     Y=Y1;
30 }
31 int main()
32 {
33     __int64 d,a,b;
34     while(scanf("%I64d%I64d",&a,&b)!=EOF)
35     {
36         d=gcd(a,b);
37         if(d!=1) {printf("sorry\n");continue;}
38         extend_GCD(a,b);
39         X=X%b;
40         if(X<0) X+=b;
41         Y=(1-X*a)/b;
42         printf("%I64d %I64d\n",X,Y);
43     }
44     return 0;
45 }

 

 

posted on 2012-09-05 10:24  奋斗青春  阅读(975)  评论(0编辑  收藏  举报