扩展欧几里得算法_扩展欧几里得递推算法

2c9237adcfda9b88c73bb8e9c56b9775.png

欧几里得算法

表示 整数 a 与 b 的最大公约数.

若 t = a % b, 则

证明略.

递推版 gcd 算法

gcd 接受变量元组 (a, b) 作为输入,输出最大公约数 (r).

我们很难直接计算出 r,但可以通过一些中间步骤逐步计算得到 r.

我们定义一个中间状态

,其中, t = c % d

定义一个状态转移过程,将一个状态映射到下一个状态.

将初始状态赋值为

,则

进行状态转移

此时

由归纳法可得,在任意一个中间状态

时,有

状态转移不能无限进行下去,要有一个终止条件,即 t = 0.

时,显然
.

在最终状态

时, d 就是最大公约数 r.

代码

int gcd(const int a, const int b) {
    int c = a, d = b, t = a % b;
    while (t) {
        c = d;
        d = t;
        t = c % d;
    }
    return d;
}

实际上,可以减少变量个数,直接使用输入时定义的变量 a, b 存放中间状态,即我们通常所见的 gcd 实现。

扩展欧几里得算法

,则扩展欧几里得算法可以在求出 r 的同时,得出二元一次方程
的一组整数解。

递推版 exgcd 算法

exgcd 是一个映射

可以这样定义中间状态

其中

继承 gcd 的状态转移过程

时,
.

此时该状态保证

, 即得解.

如何递推计算 x, y ?

无法计算

.

又注意到上式中的 d 阻断了递推,因此需要想办法用 x, y 表示 d.

这就是通常的 exgcd 递推算法.

定义状态

其中

状态转移

证明: 状态转移不会破坏状态定义

因此转移后的状态仍满足定义。

初始状态

由归纳法可得,在任意一个中间状态,有

时,

输出为

代码

typedef long long ll;
ll exgcd(const ll a, const ll b, ll &x, ll &y) {
    ll c, d, q, t, x0, y0, x1, y1, temp;
    c = a, d = b, q = a / b, t = a % b, x0 = 1, y0 = 0, x1 = 0, y1 = 1;
    while (t) {
        temp = x0, x0 = x1, x1 = temp - q * x1;
        temp = y0, y0 = y1, y1 = temp - q * y1;
        c = d;
        d = t;
        q = c / d;
        t = c % d;
    }
    x = x1, y = y1;
    return d;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值