Loading

[算法/数学]拓展欧几里得算法(EXGCD)详细推导及应用

使用场景:

  • \(ax+by=c\) 的一个特解。
  • \(ax \equiv b \ (\text{mod} \ m)\) 的一个特解。

这两个实际上是一个问题。

公式推导

  • 首先解决 \(ax+by=gcd(a,b)\) 的特解。

引入两个方程,我们通过 \(x_2,y_2\)\(x_1,y_1\) ,因此问题可以无限细分

\[ \left\{\begin{matrix} ax_1+by_1=gcd(a,b) \\ bx_2+(a \ \text{mod} \ b)y_2 = gcd(b,a \ \text{mod} \ b) \end{matrix}\right. \]

\[\because gcd(a,b)=gcd(b,a \ \text{mod} \ b) \\ \therefore ax_1+by_1 = bx_2+(a \ \text{mod} \ b)y_2 \]

\[\because a\ \text{mod}\ b = a - \left \lfloor \frac{a}{b} \right \rfloor*b \\ \therefore ax_1+by_1 = bx_2+(a - \left \lfloor \frac{a}{b} \right \rfloor*b )y_2 \]

\[ax_1+by_1 = bx_2+ay_2 - \left \lfloor \frac{a}{b} \right \rfloor*b y_2 \]

\[ax_1+by_1 = ay_2 + b(x_2- \left \lfloor \frac{a}{b} \right \rfloor * y_2) \]

\[\left\{\begin{matrix} x_1=y_2 \\ y_1=x_2- \left \lfloor \frac{a}{b} \right \rfloor * y_2 \end{matrix}\right. \]

此时我们已经通过 \(x_2,y_2\) 求得 \(x_1,y_1\) ,那么 \(x_2,y_2\) 可以继续通过 \(x_3,y_3\) 求得,以此类推。

根据欧几里得算法求GCD原理,问题一定可以被简化为:

\[b=0 \\ \therefore a*x + 0*y = gcd (a,0) \\ \therefore ax=a \\ \therefore x=1,y\in R \]

注意此处 \(y\in R\) ,而不是网络上大多数文章所说的 \(y=0\) ,也就是y在编码中实际上可以取任意值,只不过习惯上令 \(y=0\)

  • 接下来通过 \(ax'+by'=gcd(a,b)\)\(ax+by=c\)

\[\because ax'+by'=gcd(a,b) \\ \therefore ax'*\frac{c}{gcd(a,b)}+by'*\frac{c}{gcd(a,b)}=c \]

\[\therefore \left\{\begin{matrix} x= x'*\frac{c}{gcd(a,b)} \\ y= y'*\frac{c}{gcd(a,b)} \end{matrix}\right. \]

代码实现

  • C++
int Exgcd(int a, int b, int &x, int &y) {
  if (!b) {
    x = 1;
    y = 0;
    return a;
  }
  int d = Exgcd(b, a % b, x, y);
  int t = x;
  x = y;
  y = t - (a / b) * y;
  return d;
}
  • Python
def Exgcd(a, b):
    if b == 0:
        return a, 1, 0
    d, x, y = Exgcd(b, a % b)
    return d, y, x - (a // b) * y
posted @ 2024-10-06 11:05  TommyJin  阅读(694)  评论(0)    收藏  举报