关于 exgcd 求得特解的数值范围
upd 12.6:修复了一个伪证的地方()
int exgcd(int a, int b, int &x, int &y) {
if(!b) return x = 1, y = 0, a;
int d = exgcd(b, a % b, y, x);
return y -= a / b * x, d;
}
以前我写 int
的 exgcd,总是怕爆 int
而 #define int long long
,因为看上去没有任何证据说明 exgcd 得到的特解绝对值不会很大。以及如果系数是 long long
的话,那甚至不确定要不要开 __int128_t
。
事实上,我们可以证明 ax+by=gcd 由 exgcd 解出的特解保证了 x 绝对值最小。以下设 a' = \dfrac a d, b' = \dfrac b d。
- 当 b = 0 时 x = 1, y = 0 显然满足条件。
- 否则,x 为所有解中绝对值最小的显然当且仅当 |x| \leq \dfrac 1 2 |b'|。考虑归纳:b \mid a 是递归的倒数第二层,当作边界验证,解为 x = 0, y = 1,此时 |x| = 0 显然满足条件。对于 b \nmid a,按照 exgcd 的代码递归到了 by_0 + (a \bmod b)x_0 = d,得到了使得 |y_0| 最小的解,有 |y_0| \leq \dfrac 1 2 \left|\dfrac{a \bmod b} d\right|;而 x 是直接继承 x_0 的,所以有 x = x_0 = \dfrac{d - by_0}{a \bmod b},那么显然 |x| \leq \left|\dfrac d{a \bmod b}\right| + \left|\dfrac{b \cdot \frac 1{2d}(a \bmod b)}{a \bmod b}\right| \leq \left|\dfrac d{a \bmod b}\right| + \left|\dfrac 1 2 b'\right|。由于 \gcd(a \bmod b, a) = d(且 a \bmod b \neq 0),必定有 a \bmod b \geq d,于是 \left|\dfrac d{a \bmod b}\right| \leq 1。此时如果有 \mathrm{LHS} < \dfrac 1 2 就直接证毕了好吧。由于 d \mid a \bmod b,现在只要稍微考虑一下 =\dfrac 1 2 和 =1 的情况。
- \mathrm{LHS} = 1,也就是 |d| = |a \bmod b|,这显然是倒数第三轮递归,手动模拟得到 x = 1,而不可能有 b' = 0(这样一定有 b = 0,这是最后一层)或 b' = \pm1(|b| = |d| = |a \bmod b|,与 |a \bmod b| < |b| 矛盾),所以 |b'| \geq 2,也得到 |x| \leq \dfrac 1 2 |b'|。
- \mathrm{LHS} = \dfrac 1 2,那么 |d| = \dfrac 1 2 |a \bmod b|,即 |a \bmod b| = 2|d|。从 a, b 往下手动模拟 exgcd(绝对值相等视为相等):a, b\to b, 2d,下一步需要考虑 b \bmod 2d 等于多少。显然只可能等于 0 或 d,如果等于 0 的话就有 \gcd(a, b) = 2d 了,矛盾,所以只可能等于 d。于是 \to 2d, d \to d, 0,发现这是倒数第四轮。手动模拟得到 |x| = \left\lfloor\left|\dfrac{b}{2d}\right|\right\rfloor,这不完美了吗,直接证毕了。
那么 y 的情况呢?注意到当 a = b 时,exgcd 得到解为 x = 0, y = 1,不用愁;而 a \neq b 时,解 ax + by = d 和 by + ax = d 中恰好有一个的第一步是 swap(a, b)
,这使得两者解得的 (x, y) 相等,所以在 |x| 取得最小的同时,|y| 也取得最小。这意味着(除了 a 或 b 等于 0 或者 a = b 的极端情况)同时有 |x| \leq \dfrac 1 2 |b|, |y| \leq \dfrac 1 2 |a|,这样不开 long long
都不带怕的。
珍爱生命,远离抄袭!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· ASP.NET Core - 日志记录系统(二)
· 在外漂泊的这几年总结和感悟,展望未来
· 博客园 & 1Panel 联合终身会员上线
· 支付宝事故这事儿,凭什么又是程序员背锅?有没有可能是这样的...
· https证书一键自动续期,帮你解放90天限制
· 在 ASP.NET Core WebAPI如何实现版本控制?
2020-12-03 CF997C - Sky Full of Stars 题解