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(a, b) = d\) 由 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
都不帶怕的。