一、简介
扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数)。通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数——这是众所周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。
二、分析
最直观的问题使求解 有多少个整数点(x,y)满足ax+by+c==0
先看一下扩展欧几里得算法——找出一对整数(x,y),使得ax + by = gcd(a,b),x,y可能小于等于零
行列式变换求解:
其中x,y用来存放解, d用来存放a和b的最大公约数 :
#include<bits/stdc++.h>
using namespace std;
void gcd(int a,int b,int &d,int &x,int &y)
{
if(!b)
d=a, x=1, y=0;
else
{
gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
那么怎么求其他解:
- 任取一组解(x2,y2),则ax1+by1==ax2+by2(都等于gcd(a,b)==d),
- 变形得a(x1-x2)==b(y2-y1)
- 两边同时除以gcd(a,b)(a/=d ,b/=d)
- 此时a与b互素,因此(x1-x2)一定是b的整数倍,则y2-y1==ka,k为正整数
有了这个结论,很容易求出ax+by=-c
例如:求 6x+15y=9,
根据欧几里得算法得到6*(-2)+15*1=3,
两边同时乘以3,可以得到出x=-6,y=3,
所以,只需要求出d和c的最小公倍数,然后用最小公倍数除以c,得到倍数,然后将x与y分别乘以这个倍数即可
四、应用
输入方正整数a,b,n,解方程ax≡b(mod n),也就是求解ax和b关于n同余
由同余定理,ax≡b(mod n)的充要条件是ax-b是n的整数倍
那么我们设这个倍数为y ,则得到 ax-ny=b,可以用上述算法解
当a和n互素的时候,此方程有为一解