扩展欧几里得

来源:互联网 发布:苏州淘宝美工招聘 编辑:程序博客网 时间:2024/06/06 03:12

2017年3月18日 | ljfcnyali
之前一直对扩欧十分的懵懂,只会暴力的背下公式.

long long exgcd(long long a, long long b, long long &x, long long &y) {    if(b == 0) {        x = 1;        y = 0;        return a;    }    long long ans = exgcd(b, a % b, x, y);    long long temp = x;    x = y;    y = temp - a / b * y;    return ans;}

直到今天,我才真正的理解了扩展欧几里得.
首先我们先回忆一下普通的欧几里得:

long long gcd(long long a, long long b) {    if(b == 0)        return a;    else        return gcd(b, a % b);}

这种是十分简单的,那么,扩欧是干什么的呢?也就是求ax + by = gcd(a, b)中的x, y.
我们观察到:欧几里德算法停止的状态是:a=gcd,b=0,那么,这是否能给我们求解x,y提供一种思路呢?
因为,这时候,只要a = gcd的系数是1,那么只要b的系数是0或者其他值(无所谓是多少,反正任何数乘以0都等于0,但是a的系数一定要是1).
这时,我们就会有: a * 1 + b * 0 = gcd
当然这是最终状态,但是我们是否可以从最终状态反推到最初的状态呢?
假设当前我们要处理的是求出a和b的最大公约数,并求出x, y使得a * x + b * y = gcd,而我们已经求出了下一个状态:b和a%b的最大公约数,并且求出了一组x1和y1 使得:b * x1 + (a % b) * y1 = gcd,那么这两个相邻的状态之间是否存在一种关系呢?
我们知道:a % b = a – (a / b) * b(这里的”/”指的是整除,如5 / 2 = 2, 1 / 3 = 0),那么,我们可以进一步得到:

gcd = b * x1 + (a - (a / b) * b) * y1    = b * x1 + a * y1 – (a / b) * b * y1    = a * y1 + b * (x1 – a / b * y1)

对比之前我们的状态:求一组x, y使得: a * x + b * y = gcd,是否发现了什么?
这里:

x = y1y = x1 – a/b*y1

以上就是扩展欧几里德算法的全部过程,是不是理解了?
本文转自:http://ljf-cnyali.cn/index.php/archives/73

原创粉丝点击