It has been 536 days since the last update, the content of the article may be outdated.

扩展欧几里德定理

引入

对于不定方程 ax+by=cax+by=c,如果我们想求出它的整数解,我们就可以使用扩展欧几里德定理(exgcd)。

前置知识

裴蜀定理

定义

aa, bb 是不全为零的整数,则存在整数 xx, yy 使得 ax+by=gcd(a,b)\textit{ax+by=gcd(a,b)}.

证明

  1. a=0a = 0b=0b = 0 时,原式显然成立
  2. a,ba, b 都不等于 00
    • 记集合 S={ax+byx,yZax+by>0}S = \{ax + by| x,y \in Z且ax + by > 0\}
    • d=ax0+by0d=ax_0+by_0SS 中的最小正整数,现在只需证明 d=gcd(a,b)d=gcd(a,b)即可
    • a=qd+ra = qd+r,其中 q,rq, r 分别为 a/da/d 的商和余数,则有
    • r=aqd=aq(ax0+by0)=a(1qx0)+b(qy0)r=a-qd=a-q(ax_0+by_0)=a(1-qx_0)+b(-qy_0),注意到形式一致,说明 rr 也是 SS 中的元素,又 dd 为最小正整数,故 r=0r = 0 ,即 dad|a
    • 同理可得,dbd|b ,故 dgcd(a,b)d|gcd(a,b),又 gcd(a,b)ax0+by0gcd(a,b) | ax_0+by_0 ,故 d=gcd(a,b)d=gcd(a,b),证毕

扩展欧几里德定理

接下来,让我们讲解一下扩展欧几里德定理(exgcd):

  • ax1+by1=gcd(a,b)ax_1+by_1=gcd(a,b)bx2+(a mod b)y2=gcd(b,a mod b)bx_2+(a\ mod\ b)y_2=gcd(b,a\ mod\ b)
  • 由欧几里德定理可知,gcd(a,b)=gcd(b,a mod b)gcd(a,b)=gcd(b,a\ mod\ b),且 a mod b=aa/bba\ mod\ b = a-\lfloor a/b\rfloor * b
  • ax1+by1=bx2+(aa/bb)y2=ay2+b(x2a/by2)ax_1+by_1=bx_2+(a-\lfloor a/b\rfloor * b)y_2 = ay_2+b(x_2-\lfloor a/b\rfloor y_2)
  • x1=y2x_1=y_2y1=x2a/by2y_1=x_2-\lfloor a/b\rfloor y_2,到这里,我们遍可以递归求解了,注意退出条件:当 b=0b=0 时,x=1x=1y=0y=0

核心代码如下:

c++
1
2
3
4
5
6
7
8
9
10
void exgcd(int a, int b, int &x, int &y) //x,y通过引用的形式传入,以便直接更改值
{
if(!b)
{
x = 1;
y = 0;
}
exgcd(b, a%b, y, x);
y -= a/b * x;
}

可能有人会问:y -= a/b * x是什么意思呢?

  • 我们不妨假设递归结束时 x=xnx=x_ny=yny=y_n ,那么退回到上一层后有:yn1=xny_{n-1}=x_nxn1=ynx_{n-1}=y_n
  • 由前文我们知道,xn1=ynx_{n-1}=y_nyn1=xna/byny_{n-1}=x_n-\lfloor a/b\rfloor y_n,所以退回上一层后 xn1x_{n-1} 直接被求得
  • 而对于 yn1y_{n-1} ,我们发现 xn=yn1x_n=y_{n-1}yn=xn1y_n=x_{n-1},所以 yn1=yn1a/bxn1y_{n-1} =y_{n-1}-\lfloor a/b\rfloor x_{n-1} ,即原代码所示

延伸

现在我们通过扩展欧几里德定理求出了原方程的一组解,那我们能不能求出其通解呢?答案是可以的

  • 设exgcd求出的一组解为 (x1,y1)(x_1,y_1) ,待求的另一组解为 (x2,y2)(x_2,y_2)
  • 则有 ax1+by1=ax2+by2ax_1+by_1=ax_2+by_2 ,整理得 a(x1x2)=b(y2y1)a(x_1-x_2)=b(y_2-y_1)
  • 两边同时除以 gcd(a,b)gcd(a,b),得 a(x1x2)=b(y2y1)a^{\prime}(x_1-x_2)=b^{\prime}(y_2-y_1),其中 a=a/gcd(a,b)a^{\prime} = a/gcd(a,b)b=b/gcd(a,b)b^{\prime} = b/gcd(a,b)
  • 由于 aa^{\prime}bb^{\prime} 互质,故 x1x2x_1-x_2bb^{\prime} 的整数倍,即 x1x2=kbx_1-x_2 = kb^{\prime} ,故 x2=x1kbx_2=x_1-kb^{\prime} ,同理,y2=y1+kay_2=y_1+ka^{\prime}
  • 故原方程的通解为 x=x1kb/gcd(a,b)x = x_1-kb/gcd(a,b)y=y1+ka/gcd(a,b)y=y_1+ka/gcd(a,b)