[笔记]扩展欧几里得算法

扩展欧几里得算法

"那时候真好"

今天刚刚学了扩展欧几里德算法,让我很兴奋!于是我开始做同余方程,因此,我又被wyx卷了一顿!
emm,题意就是$ axequiv 1pmod{b}$求x的最小整数解。由此可以得到 (axmod b =1)(因为(1 mod b=1))即(ax+by=1)于是可以用扩展欧几里德来做了!

下列是证明

证明:

原式: (ax+by=gcd(a,b))(假设(a≥b))

  • (b=0),有(gcd(a,b)=a),此时(x=1,y=0)
  • (b eq 0),根据欧几里得定理(gcd(a,b)=gcd(b,amod b))可得
    $ ax+by = gcd(a,b)​$ $ = gcd(b,amod b)​$ (=bx'+(amod b)y' ​)


$ ax+by=bx'+(amod b)y' =bx'+(a-b*lfloor a/b floor) y'$

移项得
$ ax+by=bx'+(amod b)y' =ay'+b(x'-lfloor a/b floor y')$

根据恒等定理,有

[egin{cases} x=y'\ y=x'- lfloor a/b floor y' end{cases} ]

这有什么用呢?
(x')(y')还是不知道呀.
重新来看看我们得到的两个等式.(x)(y)(gcd(a,b)=ax+by)的解,

(x')(y')是在对(gcd(a,b))按欧几里德算法进行一步后的结果对应的贝祖等式(裴蜀)(gcd(b,amod b)=bx'+(amod b)y')的解.

也就是说,(gcd(a,b))对应的贝祖等式的解(x),(y)可以由(gcd(b,amod b))对应等式的解(x'),(y')计算得出

由于欧几里德算法最后一步为(gcd(d,0)=d),此时对应的等式的解为(x=1),(y=0),因此只要如上述代码,从(gcd(d,0))往前处理,

在进行欧几里德算法的递归的时候根据相邻两次调用间(x),(y)(x'),(y')的关系计算即可求出(ax+by=gcd(a,b))的解.

更进一步,对于任意不定式(ax'+by'=c),只需要在等式(ax+by=gcd(a,b)=d)两边乘上(c/d)即可得到解为$ x'=xcdot c/d,y'=ycdot c/d $

如何得到所有解?
实际上在之前的计算和证明中我们得到的只是不定方程的一组解,那么怎样得到所有解呢?对于一般形式(ax+by=c)有通解
(x=p+kb,y=q-ka (kin Z))
.(证明略,只要代入一下就知道为什么通解是这个了


上述证明出自扩展欧几里德算法(附证明)


代码

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

int t, x, y;

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

int main() {
    int a, b;
    cin>>a>>b;
    int ans = (exgcd(a, b) + b) % b;//可能出现负数,这个操作就是都加上b,如果是负数,那么就会变正,若为正数,因为%b,所以又会变回去。
    cout<<ans<<endl;
    return 0;
}

2018-05-24 20:13:58 初稿

2018-08-16 12:10 修订

感觉之前也是囫囵吞枣的学习,系统复习后发现了很多错误

原文地址:https://www.cnblogs.com/LMSH7/p/9533131.html