exgcd 通解(新)
什么是通解,我们知道二元一次方程,是如果只有一个式子,那么解会有无数个,而通解就是指让我们只找到一个解就可以推出其他所有解的式子。
推导
注意以下变量都为整数。
知道了定义下面就是推式子了,首先设 \(x, y\) 是 \(ax + by = \gcd(a, b)\) 的一个解,那么有
再设一个解 \(x_0,y_0\)
那么有
所以
由 \((3)\) 和 \((2)\) 得
由 \((4)\) 和 \((1)\) 得
我们要保证 \(y_0\) 是整数,且 \(y\) 又是整数, 那么 \(\frac{a}{b} \times k\) 就是整数,设 \(d = \gcd(a, b)\)
\(a = a' \times d, b = b' \times d\),这里 \(a', b'\) 互质(如果他们不互质,\(d\) 就可以通过 \(a', b'\) 的公约数变大, 这就和我们d是最大公约数就矛盾了, 所以 \(a'\) 和 \(b'\) 互质)
此时有
因为 \(a'\) 和 \(b'\) 互质,那么 \(\frac{a'}{b'} \times k\) 要是想是整数的话,\(k\) 只能是 \(b'\) 的倍数(\(k =0\) 时整个就是
\(0\) 也是整数,依旧满足要求)不然就消不掉 \(\frac{a'}{b'}\)的分母 \(b'\) ,就会产生小数, 就不是整数了,因此
又因为
所以
所以
所以
通过 \((5)\) 和 \((6)\) 可得
至此通解就出来了
更常见的是这样的
附带最小正整数解就是
对于代码中,因为 C++ 强大的取负模的特性,所以更准确代码形式的应该是
(x % (b/d) + b/d) % (b/d)
就相当于把所有的 \(\frac{kb}{d}\) 给删掉, 剩下的就是最小的正整数解。
另一种推导方式
我们设有另一组解 \(x_0 = x + k_1,\;y_0 = y + k_2\),则
即:
又因为
所以
那么可以得到
剩下的就和上面的证明一样了。
事实上这种证明方式更本质一点,所谓通解,就是使得 \(ak_1 + bk_2 = 0\) 而已。
补充
式子扩大
exgcd 二元一次等式,扩大后判断是否有整数解(小数解都是有的,但是小数解不符合我们要求)。注意这里的扩大,实际上是指乘上一个数,且扩大不一定增大,比如扩大 \(\frac 1 2\) 这虽然说是扩大,但实际上减小了(但是实际上缩小无解,可见[[裴蜀定理]])。
首先 exgcd 求出的等式 \(ax + by = d\) 肯定是有整数解的,但是等式两边扩大非整数倍后就不一定了,一定得是整数倍,如果是小数比如 \(\frac12\) 就不一定对了,比如 \(6x + 2y = 2\) 合法,但是 \(6x_0 + 2y_0 = 1\) 就是无整数解情况(\(x\) 变为 \(\frac x2 = x_0\),对于后式是求 \(x_0\),而非 \(x\))。\(ax + by = k\),\(k\) 满足扩大 \(d\) 的整数倍的条件就是 \(k \equiv 0 \pmod d,\; k = nd\),而这就是扩大判断是否有整数解的充要条件。
式子扩大后的通解
我们知道通解是 \(x = x_0 + \frac{nb}{\gcd(a, b)}\),设 \(m = \gcd(a, b),\; t = \frac {k} {\gcd(a, b)}\),等式扩大了,但是通解不变, 因为 \(a\) 没变,\(b\) 没变,原式为:
式子两边都扩大 \(t\) 倍,则有:
我们带入通解,则:
所以有:
也就是 $$axt + byt = k$$可以发现等式两边没变,也就说明通解依旧可行,对于其他情况,也可以这样证明通解的可行性。