您的位置:首页 > 其它

扩展欧几里得应用分析

2015-06-03 16:10 169 查看
原理推导:

首先我们定义:设a和b不全为0,则存在整数x和y,使得gcd(a,b)=ax+by。这就是扩展欧几里得的算法描述。

扩展欧几里得算法是用来求解二元一次方程。对于方程Ax+By=C,其中A,B,C为整数,求出满足等式的整数x和y。考虑到给出的方程不一定是最简形式,所以我们需要先化为最简式,设d=gcd(A,B),那么化简后的方程为:ax+by=c,其中a=A/d,b=B/d,c=C/d;

此时,gcd(a,b)=1,先将方程ax+by=gcd(a,b)=1解出后,设x0,y0为方程的特解,那么原方程的最终解为c*x0,c*y0.现在问题来了,怎么求方程ax+by=1的解呢?这就是我们要讨论的扩展欧几里得了。

扩展欧几里得是求方程ax+by=gcd(a,b)的解。设a>b,当b=0时,gcd(a,b)=a,此时x=1,y=0;否则我们设:

a*x1+b*y1=gcd(a,b);

b*x2+(a mod b)*y2=gcd(b,a mod b);

欧几里得算法中,我们有gcd(a,b)=gcd(b.a mod b),所以我们进一步得到:

a*x1+b*y1 = b*x2+(a mod b)*y2 = b*x2+(a-|_ a/b _|*b)*y2 = a*y2+b*(x2-|_ a/b _|*y2);

所以有:x1=y2; y1=x2-|_ a/b _|*y2;

举个例子来说吧,考虑二元一次方程48x+30y=gcd(48,30),我们先通过欧几里得递归求出它们的最大公约数6,然后逐层回溯得到x和y:

递归过程:48=1×30+18

30=1×18+12

18=1×12+6

12=2×6+0

回溯过程:6=18-(1×12)

=18-1×(30-18×1)

=18-1×(30-(48-30×1)×1)

=48×2-30×3

递归实现代码如下:

void exgcd(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
exgcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
}


非递归实现代码如下:

typedef long long LL;
LL exgcd(LL m,LL &x,LL n,LL &y)
{
LL x1,y1,x0,y0;
x0=1;x1=0;
y0=0;y1=1;
LL r=(m%n+n)%n;
LL t=(m-r)/n;
x=0;y=1;
while(r)
{
x=x0-t*x1;
y=y0-t*y1;
x0=x1;y0=y1;
x1=x;y1=y;
m=n;n=r;r=m%n;
t=(m-r)/n;
}
return n;
}


应用与分析:

上面讲了扩展欧几里得算法的原理,通过这个方法可以得到二元一次方程的特解,实际上,得到特解之后,就可以得到通解,如下:

x=c*x0-b*t;

y=c*y0+a*t;

其中t∈Z,将上述解代入方程,有:

ax+by=a*(c*x0-b*t)+b*(c*y0+a*t)=a*c*x0+b*c*y0=(a*x0+b*y0)*c=c;

在ACM中,扩展欧几里得的应用主要包括:

(1)求解不定方程;

(2)求解模的逆元;

(3)求解同余方程;

例题:

POJ1061µhttp://poj.org/problem?id=1061

http://acm.hit.edu.cn/hoj/problem/view?id=2815

http://poj.org/problem?id=2142

http://codeforces.com/problemset/problem/7/C
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: