先上代码:
void Exgcd_1(int a, int b, int &x, int &y) {
if (!b)
x = 1, y = 0;
else {
Exgcd_1(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
}
}
具体执行过程
首先,扩展欧几里得算法的目的是找到整数 x 和 y,使得 ax + by = gcd(a, b)。这个算法依赖于递归地求解bx' + (a % b)y' = gcd(b, a % b)
,并基于这个解来找到 x 和 y。
这里的关键在于理解递归返回后如何根据 x’ 和 y’ 来计算 x 和 y。根据扩展欧几里得算法,我们有以下递推关系:
x = y'
y = x' - (a / b) * y'
其中 x’ 和 y’ 是对 b 和 a % b 调用扩展欧几里得算法时得到的解。
现在,让我们通过一个具体的例子来演示这个过程:
假设我们要计算 Exgcd_1(48, 18, x, y)
,即找到 x 和 y 使得 48x + 18y = gcd(48, 18)。
初始调用 Exgcd_1(48, 18, x, y)
。
因为 18 != 0,递归调用 Exgcd_1(18, 48 % 18, x', y')
,即 Exgcd_1(18, 12, x', y')
。
继续递归调用 Exgcd_1(12, 18 % 12, x'', y'')
,即 Exgcd_1(12, 6, x'', y'')
。
再次递归调用 Exgcd_1(6, 12 % 6, x''', y''')
,即 Exgcd_1(6, 0, x''', y''')
。
递归基础情况:当 b = 0 时,gcd(6, 0) = 6,此时 x''' = 1, y''' = 0
,返回。
现在开始回溯并计算 x 和 y:
在 Exgcd_1(6, 0, x''', y''')
返回后,我们知道 6 * 1 + 0 * 0 = 6 的解是 x''' = 1, y''' = 0
。
回到 Exgcd_1(12, 6, x'', y'')
,我们需要计算 x’’ 和 y’’ 使得 12 * x’’ + 6 * y’’ = 6。根据递推关系,我们有:
x'' = y''' = 0
y'' = x''' - (12 / 6) * y''' = 1 - 2 * 0 = 1
回到 Exgcd_1(18, 12, x’, y’),我们需要计算 x’ 和 y’ 使得 18 * x’ + 12 * y’ = 6。再次应用递推关系:
x' = y'' = 1
y' = x'' - (18 / 12) * y'' = 0 - 1 * 1 = -1
最后回到 Exgcd_1(48, 18, x, y),我们需要计算 x 和 y 使得 48 * x + 18 * y = 6。应用递推关系:
x = y' = -1
y = x' - (48 / 18) * y' = 1 - 2 * (-1) = 3
因此,对于 Exgcd_1(48, 18, x, y),我们得到的解是 x = -1, y = 3,这意味着 48 * (-1) + 18 * 3 = 6。