什么是通解,我们知道二元一次方程,是如果只有一个式子,那么解会有无数个,而通解就是指让我们只找到一个解就可以推出其他所有解的式子。
注意以下变量都为整数。
知道了定义下面就是推式子了,首先设
x
,
y
x, y
x,y 是
a
x
+
b
y
=
gcd
(
a
,
b
)
ax + by = \gcd(a, b)
ax+by=gcd(a,b) 的一个解,那么有
y
=
[
gcd
(
a
,
b
)
−
a
x
]
÷
b
(1)
y = \left[\gcd(a, b) - ax \right] \div b \tag 1
y=[gcd(a,b)−ax]÷b(1)
再设一个解
x
0
,
y
0
x_0,y_0
x0,y0
x
0
=
x
+
k
(2)
x_0 = x + k \tag 2
x0=x+k(2)
那么有
a
x
0
+
b
y
0
=
gcd
(
a
,
b
)
ax_0 + by_0 = \gcd(a, b)
ax0+by0=gcd(a,b)
所以
y
0
=
[
gcd
(
a
,
b
)
−
a
x
0
]
÷
b
(3)
y_0 = [\gcd(a, b) - ax_0] \div b \tag{3}
y0=[gcd(a,b)−ax0]÷b(3)
由
(
3
)
(3)
(3) 和
(
2
)
(2)
(2) 得
y 0 = [ gcd ( a , b ) − a x − a k ] ÷ b = [ gcd ( a , b ) − a x ] ÷ b − a b × k (4) y_0 = \left[\gcd(a, b) - ax - ak \right] \div b = [\gcd(a, b) - ax] \div b - \frac{a}{b} \times k \tag4 y0=[gcd(a,b)−ax−ak]÷b=[gcd(a,b)−ax]÷b−ba×k(4)
由
(
4
)
(4)
(4) 和
(
1
)
(1)
(1) 得
y
0
=
y
−
a
b
×
k
(5)
y_0 = y - \frac{a}{b} \times k \tag 5
y0=y−ba×k(5)
我们要保证
y
0
y_0
y0 是整数,且
y
y
y 又是整数, 那么
a
b
×
k
\frac{a}{b} \times k
ba×k 就是整数,设
d
=
gcd
(
a
,
b
)
d = \gcd(a, b)
d=gcd(a,b)
a
=
a
′
×
d
,
b
=
b
′
×
d
a = a' \times d, b = b' \times d
a=a′×d,b=b′×d,这里
a
′
,
b
′
a', b'
a′,b′ 互质(如果他们不互质,
d
d
d 就可以通过
a
′
,
b
′
a', b'
a′,b′ 的公约数变大, 这就和我们d是最大公约数就矛盾了, 所以a’和b’互质)
此时有
a
b
×
k
=
a
′
b
′
×
k
\frac{a}{b} \times k = \frac{a'} {b'} \times k
ba×k=b′a′×k
因为
a
′
a'
a′ 和
b
′
b'
b′ 互质,那么
a
′
b
′
×
k
\frac{a'}{b'} \times k
b′a′×k 要是想是整数的话,
k
k
k 只能是
b
′
b'
b′ 的倍数(
k
=
0
k =0
k=0 时整个就是
0
0
0 也是整数,,依旧满足要求)不然就消不掉
a
′
b
′
\frac{a'}{b'}
b′a′的分母
b
′
b'
b′ ,就会产生小数, 就不是整数了,因此
k
=
n
×
b
′
,
n
∈
Z
k = n \times b', n \in \mathbb{Z}
k=n×b′,n∈Z
又因为
b
′
∗
d
=
b
b' * d = b
b′∗d=b
所以
b
′
=
b
÷
d
b' = b \div d
b′=b÷d
所以
k
=
n
b
d
k = \frac{nb}{d}
k=dnb
所以
x
0
=
x
+
n
∗
b
/
d
(6)
x_0 = x + n*b/d \tag6
x0=x+n∗b/d(6)
通过
(
5
)
(5)
(5) 和
(
6
)
(6)
(6) 可得
y
0
=
y
−
n
a
d
(7)
y_0 = y - \frac {na}{d} \tag7
y0=y−dna(7)
至此通解就出来了
x
0
=
x
+
b
d
×
n
y
0
=
y
−
a
d
×
n
\begin{aligned} x_0 &= x + \frac{b}{d} \times n \\ y_0 &= y - \frac{a}{d} \times n \end{aligned}
x0y0=x+db×n=y−da×n
更常见的是这样的
x
0
=
x
+
k
×
b
d
,
k
∈
Z
y
0
=
y
−
k
×
a
d
\begin{aligned} x_0 &= x + k\times \frac{b}{d},k\in \mathbb{Z} \\ y_0 &= y - k \times \frac{a}{d} \end{aligned}
x0y0=x+k×db,k∈Z=y−k×da
附带最小正整数解就是
x
m
o
d
b
d
y
m
o
d
a
d
\begin{aligned} x & \bmod \frac{b}{d}\\ y & \bmod \frac{a}{d} \end{aligned}
xymoddbmodda
对于代码中,因为 C++ 强大的取负模的特性,所以更准确代码形式的应该是
(x % (b/d) + b/d) % (b/d)
就相当于把所有的 k b d \frac{kb}{d} dkb 给删掉, 剩下的就是最小的正整数解。