欧几里得算法

注意:本篇文章会涉及到较多的数论的符号,如果有些符号您不认识,可以跳转到数论之基础一文查看某符号的定义

⋅ 欧几里得算法 ·欧几里得算法 欧几里得算法

1 、 g c d ( a , b ) = g c d ( b , a % b ) 1、gcd(a, b) = gcd(b, a\%b) 1gcd(a,b)=gcd(b,a%b)

( a , b ) (a, b) (a,b) ( b , a % b ) (b, a\%b) (b,a%b)的最大公约数相同,这是辗转相除法的基本原理;

2 、 l c m ( a , b ) = a × b g c d ( a , b ) 2、lcm(a, b) = \dfrac {a \times b}{gcd(a,b)} 2lcm(a,b)=gcd(a,b)a×b

l c m lcm lcm是最大公倍数

为了避免 a × b a \times b a×b l o n g l o n g long\quad long longlong,最好写成 a / g c d ( a , b ) ∗ b a/ gcd(a,b) * b a/gcd(a,b)b的形式;

3 、 3、 3辗转相除法的代码实现:

int gcd(int a, int b)
{
    return b==0 ? a : gcd(b, a%b);
}

⋅ 拓展欧几里得算法 ·拓展欧几里得算法 拓展欧几里得算法

前置知识:裴蜀定理

1 、 1、 1一般用于求解 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的解。

​ 当 b = 0 b=0 b=0时, a x + b y = a ax+by=a ax+by=a,故而 x = 1 , y = 0 x=1, y=0 x=1,y=0.

​ 当 b ≠ 0 b\neq0 b=0时:
∵ g c d ( a , b ) = g c d ( b , a % b ) 则 : b x ′ + ( a % b ) × y ′ = g c d ( b , a % b ) b x ′ + ( a − ⌊ a / b ⌋ ) × y ′ = g c d ( b , a % b ) a y ′ + b × ( x ′ − ⌊ a / b ⌋ × y ′ ) = g c d ( b , a % b ) ∴ x = y ′ , y = x ′ − ⌊ a / b ⌋ ∗ y ′ \begin{aligned} \because gcd(a,b)=gcd(b, a\%b) \\ 则:bx^{'} + (a\%b) \times y^{'} = gcd(b, a\%b) \\ bx^{'} + (a-\lfloor a/b \rfloor) \times y^{'}=gcd(b, a\%b) \\ ay^{'}+b \times (x^{'}-\lfloor a/b \rfloor \times y^{'})=gcd(b, a\%b) \\ \therefore x = y^{'}, \quad y = x^{'}-\lfloor a/b \rfloor * y^{'} \end{aligned} gcd(a,b)=gcd(b,a%b):bx+(a%b)×y=gcd(b,a%b)bx+(aa/b⌋)×y=gcd(b,a%b)ay+b×(xa/b×y)=gcd(b,a%b)x=y,y=xa/by

则有C++代码实现如下:

int exgcd(int a, int b, int &x, int &y)
{
    if(b == 0) {
		x = 1, y = 0;
        return a;
    }
    int x1, y1, gcd;
    gcd = exgcd(b, a%b, x1, y1);
    x = y1, y = x1 - a/b*y1;  //C++中的两个整数相除自动会下取整
    return gcd;
}

另一种证明方法及代码实现:

b = 0 b=0 b=0时, a x + b y = a ax+by=a ax+by=a,故而 x = 1 , y = 0 x=1, y=0 x=1,y=0.

b ≠ 0 b\neq0 b=0时:
∵ g c d ( a , b ) = g c d ( b , a % b ) = g c d ( a % b , b ) b y ′ + a % b × x ′ = g c d ( a % b , b ) b y ′ + x ′ ( a − ⌊ a / b ⌋ × b ) = g c d ( a % b , b ) a x ′ + b ( y ′ − ⌊ a / b ⌋ × x ′ ) = g c d ( a % b , b ) ∴ x = x ′ , y = y ′ − ⌊ a / b ⌋ × x ′ \begin{aligned} \because gcd(a, b) = gcd(b, a\%b) = gcd(a\%b, b) \\ by^{'} + a\%b \times x^{'} = gcd(a\%b, b) \\ by^{'} + x^{'}(a - \lfloor a/b \rfloor \times b) = gcd(a\%b, b) \\ ax^{'} + b(y^{'} - \lfloor a/b \rfloor \times x^{'}) = gcd(a\%b, b) \\ \therefore x = x^{'}, \quad y = y^{'} - \lfloor a/b \rfloor \times x^{'} \end{aligned} gcd(a,b)=gcd(b,a%b)=gcd(a%b,b)by+a%b×x=gcd(a%b,b)by+x(aa/b×b)=gcd(a%b,b)ax+b(ya/b×x)=gcd(a%b,b)x=x,y=ya/b×x
则有C++代码实现如下:

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;
}

我个人喜好第二种证明方式,因为比较好理解,代码也相对而言比较容易实现。

2 、 2、 2对于求解更一般的方程 a x + b y = c ax + by = c ax+by=c

d = g c d ( a , b ) d = gcd(a, b) d=gcd(a,b),则其有解当且仅当 d ∣ c . d|c. dc.

求解方法:

用拓展欧几里得求出 a x 0 + b y 0 = d ax_0 + by_0 = d ax0+by0=d的解.

a ( x 0 ∗ c / d ) + b ( y 0 ∗ c / d ) = c a(x_0 * c/d) + b(y_0 * c/d) = c a(x0c/d)+b(y0c/d)=c

故特解为 x ′ = x 0 ∗ c / d , y ′ = y 0 ∗ c / d x^{'} = x_0 * c/d, \quad y^{'} = y_0 * c/d x=x0c/d,y=y0c/d.

通解 = 特解 + 齐次解 通解 = 特解 + 齐次解 通解=特解+齐次解,齐次解即为 a x + b y = 0 ax + by = 0 ax+by=0的解

故而通解为 x = x ′ + k ∗ b / d , y = y ′ − k ∗ a / d , k ∈ z x = x^{'} + k * b/d, \quad y = y^{'} - k * a/d, \quad k \in z x=x+kb/d,y=yka/d,kz

若令 t = b / d , t = b/d, \quad t=b/d,则对于 x x x的最小非负整数解为 ( x ′ % t + t ) % t (x^{'}\%t + t) \% t (x%t+t)%t

然后将 x x x代入原式,即可得到 y y y的解.

3 、 3、 3应用:求解一次同余方程 a x ≡ b (   m o d   m ) ax \equiv b(\bmod m) axb(modm)

则等价于求:
a x = m × ( − y ) + b a x + m y = b ax = m \times (-y) + b \\ ax + my = b ax=m×(y)+bax+my=b
有解的条件为 g c d ( a , m ) ∣ b gcd(a, m)|b gcd(a,m)b,然后用拓展欧几里得求解即可.

特别的,当 b = 1 b = 1 b=1 a a a m m m互质时,则所求 x x x即为 a a a的逆元.

原创文章,如需转载,请标明出处。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡沛玮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值