「欧几里得与扩展欧几里得算法」学习笔记

$$y-=x*(a/b)$$

$$(c/g(x_0+k*b/g),c/g(y_0-k*a/g))$$

欧几里得算法

 (gcd(a, b)) 表示 (a,b) 的最大公约数。

欧几里得辗转相除法:

$gcd(0,a) = a$

$gcd(a,b) = gcd(b, a mod b), b > 0$

算法证明

  设 $ a = bq + r $,则需证明的是 $ gcd(a,b) = gcd(b, r) $

  可以通过证明$ (a,b) $的任何公因子必定也是$ (b,r) $的公因子,且$ (b,r) $的任何公因子必定也是$ (a,b) $的公因子

  设(d)为(a, b)的任意一个约数 $ (d > 0)$,则有(d|a, d|b)。可以设(a = sd, b = td) ((s, t) 为整数)

  ∴ (r = a - bq = sd - tdq = d(s - tq))   ∴ (d|r)

  故$ (a,b) $的所有约数都是( (b,r))的约数。

  可再次证明( (b,r) )的所有约数都是( (a,b))的约数。

  故 $ gcd(a,b) = gcd(b, r) $

扩展欧几里得算法 EXGCD

Exgcd用来求解方程:$ ax + by = gcd(a,b) $ (关于解的存在性证明可参见 贝祖定理 )

很明显该方程的解不止一个。先考虑解出一组特解

求解过程

特殊的,当$b = 0$时,$gcd(a,b) = a$,故解得$x = 1, y = 0$

一般的,设:$$ egin{cases} ax_1 + by_1 = gcd(a,b) \ bx_2 + (a\%b)y_2 = gcd(b,a\%b) end{cases} $$

由欧几里得算法可得$gcd(a,b) = gcd(b, a\%b)$,因此:$$ ax_1 + by_1 = bx_2 + (a\%b)y_2 $$$$ = bx_2 + (a - left lfloor a / b ight floor*b)y_2 $$$$ = bx_2 + ay_2 - left lfloor a / b ight floor*by_2 $$$$ = ay_2 + b(x_2 - left lfloor a / b ight floor y_2) $$

因此$$ax_1 + by_1 = ay_2 + b(x_2 - left lfloor a / b ight floor y_2)$$

由恒等式的性质可得一组特解:$$ egin{cases} x_1 = y_2 \ y_1 = x_2 - left lfloor a / b ight floor * y_2 end{cases} $$

因此倒推即可

void exgcd(int a, int b, int &g, int &x, int &y){
    if(!b){
        g = a; x = 1, y = 0;
        return;
    }
    exgcd(b,a%b,g,y,x);
    y -= x*(a/b);
}

通解求法

设$ k_1 = left lfloor a / gcd(a,b) ight floor , k_2 = left lfloor b / gcd(a,b)  ight floor$ 。$k_1, k_2$一定互质

同时除以$gcd(a,b)$,得$ax / gcd(a,b) + by / gcd(a,b) = 1$,即$ k_1x + k_2y = 1 $

要求得通解,并使等式仍然成立,(x, y)不可能同时变大或变小,不然等号不能成立。故(x, y)的大小变化相反。

设(x)增大(d_1),(y)减小(d_2), 可得(a(x + d_1) + b(y - d_2) = gcd(a, b))

通解即为( (x + k * d_1, y - k * d_2) ) (k为常数,且为整数)

与前面的做法相同,两边同时除以(gcd(a,b)),可得$$a(x + d_1) / gcd(a,b) + b(y - d_2)  / gcd(a,b) = 1$$

即$$k_1(x + d_1) + k_2(y - d_2) = 1$$

由于$k_1x + k_2y = 1$, 两边同时减去1, 得$$k_1d_1 =  k_2d_2$$

由于(k_1, k_2)互质,故(d_1, d_2)一定可以满足$$k_1 = d_2, k_2 = d_1$$

因此代入可得$$a(x + k_2) + b(y - k_1) = gcd(a, b)$$

因此通解为$$ (x + k * k_2, y - k * k_1) $$

故解得通解为$$ (x + k * left lfloor b / gcd(a,b)  ight floor, y - k * left lfloor a / gcd(a,b)  ight floor) $$

求解线性不定方程

求解$ax + by = c$

当$gcd(a,b) | c$时方程一定有解,否则无解

在方程 $ax_0 + by_0 = gcd(a,b) $ 两边同时乘以 $c / gcd(a,b)$ 可得 $ ax_0 * c / gcd(a,b) + by_0 * c / gcd(a,b) = c $

在(a, b)的值并没有改变的情况下,原方程的解就是:$$ egin{cases} x = x_0 * c / gcd(a,b) \ y = y_0 * c / gcd(a,b) end{cases} $$

关于最小正整数解

由于$x$的通解是$x + k * b / gcd(a,b)$,因此最小正整数解为$x mod (b / gcd(a,b))$。前提是保证$b / gcd(a,b) > 0$。而会出现$b / gcd(a,b) < 0$的情况只有$a,b$同负或$b$为负数,因此特判$b$的正负即可

注意当$x<0$时模一遍仍然为负数,所以需要模两遍:$$x' = (x mod (b / gcd(a,b)) + (b / gcd(a,b)) mod  (b / gcd(a,b)$$

求解线性同余方程

形如(ax≡b (mod m))
由原方程(ax≡b (mod m))很容易推得( ax - b ) 是(m)的倍数。不妨设(ax - b)是(m)的(y)倍。则有方程$ ax - b = my $

移项即可得$ ax - my = b $ 求不定方程即可