ax+by=gcd(a,b)求解
简单推导
假设有ax1+by1=gcd(a,b)ax_{1}+by_{1}=gcd(a,b)ax1+by1=gcd(a,b)成立
由欧几里得算法知gcd(a,b)=gcd(b,a mod b)gcd(a,b)=gcd(b,a\bmod b)gcd(a,b)=gcd(b,amodb)
又有bx2+(a mod b)y2=gcd(b,amod b)bx_{2}+(a\bmod b)y_{2}=gcd(b,a\mod b)bx2+(amodb)y2=gcd(b,amodb)
合并得ax1+by1=bx2+(a mod b)y2ax_{1}+by_{1}=bx_{2}+(a\bmod b)y_{2}ax1+by1=bx2+(amodb)y2
a mod b=a−⌊a/b⌋∗ba\bmod b=a- \lfloor a/b \rfloor *bamodb=a−⌊a/b⌋∗b
带入上式得ax1+by1=bx2+(a−⌊a/b⌋∗b)y2ax_{1}+by_{1}=bx_{2}+(a- \lfloor a/b \rfloor*b)y_{2}ax1+by1=bx2+(a−⌊a/b⌋∗b)y2
整理后得ax1+by1=ay2+b∗(x2−⌊a/b⌋y2)ax_{1}+by_{1}=ay_{2}+b*(x_{2}- \lfloor a/b \rfloor y_{2})ax1+by1=ay2+b∗(x2−⌊a/b⌋y2)
所以最后有
{x1=y2y1=x2−⌊a/b⌋y2\begin{cases}
x_{1}=y_{2}\quad \\
y_{1}=x_{2}-\lfloor a/b \rfloor y_{2}\quad
\end{cases}{x1=y2y1=x2−⌊a/b⌋y2
既然有了这样的递归关系,那么边界呢
显然gcd(a,0)=agcd(a,0)=agcd(a,0)=a
即在b=0b=0b=0时有x=1,y=0x=1,y=0x=1,y=0使得a∗1+b∗0=gcd(a,b)a*1+b*0=gcd(a,b)a∗1+b∗0=gcd(a,b)成立
那么只要在b==0b==0b==0时返回x=1,y=0x=1,y=0x=1,y=0即可一步一步回推出原方程的解
代码实现
void exgcd(int a,int b,int &x,int &y)
{
if(b==0){x=1;y=0;return a;}
int gcd=exgcd(b,a%b,x,y);
int tp=x;
x=y; y=tp-a/b*y;
return gcd;
}
拓展
上述代码仅仅求出了方程的一组解,但其实答案远远不止一组
怎么求出剩下的解呢
当前以已出的解为x1,y1x_{1},y_{1}x1,y1,设下一组解为x1+s1,y1+s2x_{1}+s_{1},y_{1}+s_{2}x1+s1,y1+s2
那么有a(x1+s1)+b(y1+s2)=gcd(a,b)a(x_{1}+s_{1})+b(y_{1}+s_{2})=gcd(a,b)a(x1+s1)+b(y1+s2)=gcd(a,b)
与ax1+by1=gcd(a,b)ax_{1}+by_{1}=gcd(a,b)ax1+by1=gcd(a,b)化简后得
as1=−bs2as_{1}=-bs_{2}as1=−bs2
s1s2=−ba=−b/gcda/gcd\frac {s_{1}}{s_{2}}=-\frac ba=-\frac {b/gcd}{a/gcd}s2s1=−ab=−a/gcdb/gcd
为了让s1,s2s_{1},s_{2}s1,s2取值最小(为了得到最小正周期)
显然可以让等式右边上下同时除以gcd(a,b)gcd(a,b)gcd(a,b)
这样我们就得到了所有解的关系式
{x2=x1+bgcd(a,b)∗ky2=y1−agcd(a,b)∗k,k∈Z\begin{cases}
x_{2}=x_{1}+\frac {b}{gcd(a,b)}*k\quad \\
y_{2}=y_{1}-\frac {a}{gcd(a,b)}*k\quad
\end{cases},k\in Z{x2=x1+gcd(a,b)b∗ky2=y1−gcd(a,b)a∗k,k∈Z
特别的,原方程的最小非负整数解的关系式为
x=(x1 mod bgcd(a,b)+bgcd(a,b)) mod bgcd(a,b)x=(x_{1}\bmod \frac {b}{gcd(a,b)}+\frac {b}{gcd(a,b)})\bmod \frac {b}{gcd(a,b)}x=(x1modgcd(a,b)b+gcd(a,b)b)modgcd(a,b)b
假如还需要判断方程是否存在正整数解
由于一组解x,y在变化过程中变化方向是相反的,即一个增大一个减小
那么只需要判断在x取最小正整数解时对应的y是否大于0即可
ax+by=c求解
简单推导
(以下简记gcd(a,b)gcd(a,b)gcd(a,b)为gcdgcdgcd)
假设有ax1+by1=gcdax_{1}+by_{1}=gcdax1+by1=gcd成立
令等式两边同时乘以cgcd\frac {c}{gcd}gcdc
有acx1gcd+bcy1gcd=ca\frac {cx_{1}}{gcd}+b\frac {cy_{1}}{gcd}=cagcdcx1+bgcdcy1=c成立
所以我么就可以先用欧几里得算法求出x1,y1x_{1},y_{1}x1,y1
那么x=cx1gcd,y=cy1gcdx=\frac {cx_{1}}{gcd},y=\frac {cy_{1}}{gcd}x=gcdcx1,y=gcdcy1就是原方程的一组解
不过根据裴蜀定理
这样的方程存在解的必要条件为gcd(a,b)∣cgcd(a,b)|cgcd(a,b)∣c
同样用与上述类似的方法推导出所有解的关系式
{x2=cx1gcd+bgcd(a,b)∗ky2=cy1gcd−agcd(a,b)∗k,k∈Z\begin{cases}
x_{2}=\frac {cx_{1}}{gcd}+\frac {b}{gcd(a,b)}*k\quad \\
y_{2}=\frac {cy_{1}}{gcd}-\frac {a}{gcd(a,b)}*k\quad
\end{cases},k\in Z{x2=gcdcx1+gcd(a,b)b∗ky2=gcdcy1−gcd(a,b)a∗k,k∈Z
原方程的最小非负整数解的关系式为
x=(cx1gcd mod bgcd(a,b)+bgcd(a,b)) mod bgcd(a,b)x=(\frac {cx_{1}}{gcd}\bmod \frac {b}{gcd(a,b)}+\frac {b}{gcd(a,b)})\bmod \frac {b}{gcd(a,b)}x=(gcdcx1modgcd(a,b)b+gcd(a,b)b)modgcd(a,b)b
同余式ax≡\equiv≡ c(mod b)求解
简单推导
由ax≡c(modb)ax\equiv c(mod b)ax≡c(modb)不难得到
(ax−c) mod b=0(ax-c)\bmod b=0(ax−c)modb=0
即一定有整数y使得ax+by=cax+by=cax+by=c成立
问题转化为上一模型
然而由于是同余式求解
事实上转化等式后求出的许多解在膜b意义下是相同的
所以我们需要找出所有膜b意义下不同的解
观察上一模型的关系式
{x2=cx1gcd+bgcd(a,b)∗ky2=cy1gcd−agcd(a,b)∗k\begin{cases} x_{2}=\frac {cx_{1}}{gcd}+\frac {b}{gcd(a,b)}*k\quad \\ y_{2}=\frac {cy_{1}}{gcd}-\frac {a}{gcd(a,b)}*k\quad \end{cases}{x2=gcdcx1+gcd(a,b)b∗ky2=gcdcy1−gcd(a,b)a∗k
我们发现k取[0,gcd(a,b)−1][0,gcd(a,b)-1][0,gcd(a,b)−1]时符合要求
恰好有gcd(a,b)个膜b意义下的不同解