扩展欧几里得挺早就会了,但是当时不会证明,现在可以自己推导出来了,下面说一下推导过程。
首先给你a,b,让你求出一组x,y,满足ax+by=gcd(a,b).这个gcd是很轻松可以得到的,但是x和y呢?其实我们也可以在求gcd的时候顺便得到一组解。
先看看我们是怎么求gcd的:
设ans=gcd(b,a%b)。那么最后一步终止条件是什么呢?是b=0。
从这里我们可以发现此时,ans*x+0*y=ans,这个时候我们可以看出x和y分别是1和0时肯定满足条件。
此时我们就得到了终止条件时候的x和y的值了。但是,每一次相邻的x和y有没有什么关系呢?答案是有的。
我们令c=gcd(a,b)
第一步有 ax1+by1=c
下一步就有 bx2+(a%b)y2=c, 我们对这一步的公式进行变形。
首先可以发现a%b=a-(a/b)*b, 我们带入就得到bx2+(a-(a/b)*b)y2=c
移项合并后就有ay2+b[x2-(a/b)*y2]=c
因此,我们发现其实x1=y2,y1=x2-(a/b)*y2, 依靠这种上下步之间的关系,我们就可以得到最外层的一组解了。
int e_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=e_gcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-(a/b)*y;
return ans;
}
我们还可以发现当ax+by=n而gcd(a,b)=d时,我们也可以得到一组解,方法是得到x后, x*(n/d)就可以了,还是很方便的。
当然,我们还要知道怎么得到所有解。这个很容易就可以推导,我直接给出公式: 令A=a/gcd(a,b), B=b/gcd(a,b), 一组解为x0,y0, 则所有解为x=x0+B*t, y=y0-A*t, t为任意整数。
除此之外,还有一个名叫乘法逆元的东西,其实就是用到扩展欧几里得。ax≡1(mod b) 称x为a关于b的乘法逆元,其实就是求ax+by=1的解。
为什么叫乘法逆元呢?因为a*x同余1,类比数学上的其他许多逆的定义,a与x显然互为逆。
最后补充个定理:
1. 如果gcd(a,b)=1,则ax≡c(mod b)有唯一解。
求解很显然,有了上面的知识后,我们发现,逆元只有一个或者没有,扩展欧几里得做一次就可以了。