说实话,数论只会gcd,这样可不行啊,只好补一补了
扩展欧几里德算法,乍听挺高端的,很久以前就听说了,不过一回都没写过,现在看了一下,没有想象中的难理解
首先,要清楚扩展欧几里德算法求的是什么
对于形如ax+by=gcd(a,b)的不定方程来说,一定存在一组整数解,使得不定方程成立,那么,扩欧算法就是用来求这样一组x,y的
假设a1,b1是在计算gcd的过程中由a0,b0,转化过来的,即a1=b0,b1=a0%b0,那么有b1=a0-k*b0,((k=(int)(a0/b0))
用a0,b0替代a1,b1,整理得
a0*y1+b0*(a1-k*y1)=gcd(a1,b1)=gcd(a0,b0) 且a0*x0+b0*y0=gcd(a0,b0)
因此可以通过递归的方法来求出x1,y1,进而由上式的到的x0=y1,y0=x1-k*y1来求出x0,y0
递归的边界是当b=0时,此时gcd(a,b)=a,对于ax+by=gcd(a,b)来说,a=1,b=0
代码如下:
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
扩欧水题同余方程:
#include <cstdio>
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main()
{
int a,b,x,y;
scanf("%d%d",&a,&b);
int d=exgcd(a,b,x,y);
x/=d;
printf("%d\n",(x%b+b)%b);
return 0;
}