数论专题-二元一次不定方程

对于不定方程 \(ax + by = c\),求:

  • 若该方程有整数解,且有正整数解,求正整数解的数量、正整数解中 \(x\) 的最小值、正整数解中 \(y\) 的最小值、正整数解中 \(x\) 的最大值、正整数解中 \(y\) 的最大值。
  • 若该方程有整数解,没有正整数解,求整数解中 \(x\) 的最小正整数值、\(y\) 的最小正整数值。

显然,根据裴蜀定理,如果 \(\gcd(a, b) \nmid c\),则方程无解。

::::info[裴蜀定理]
\(a, b\) 是不全为零的整数,那么,对于任意整数 \(x, y\),都有 \(\gcd(a, b) \mid ax+by\) 成立,并且,存在整数 \(x, y\),使得 \(ax + by = \gcd(a, b)\) 成立。

:::info[证明]
\(d = \gcd(a, b)\)。因为 \(d \mid a, b\),所以存在整数 \(p, q\),使得 \(a = pd, b = qd\) 成立,因此,总有:

\[ax + by = d(px + qy) \]

说明 \(d \mid ax + by\)

考虑 \(a, b\)\(\ne 0\) 的情况,如果 \(a\)\(b\)\(0\),显然有 \((x, y) = (1, 0)/(0, 1)\) 使得 \(ax + by = \gcd(a, b)\) 成立。

因为 \(\gcd(a, b) = \gcd(-a, b) = \gcd(a, -b)\),设 \(a, b > 0\)

考虑辗转相除:

\[\begin{cases} a = q_1b + r_1, & 0 \le r_1 < b \\ b = q_rr_1 + r_2, & 0 \le r_2 < r_1 \end{cases} \]

\[\begin{cases} r_1= q_3r_2 + r_3, & 0 \le r_3 < r_2 \\ r_2= q_4r_3 + r_4, & 0 \le r_4 < r_3 \\ \dots \\ r_{n - 2} = q_nr_{n - 1} + r_n, & 0 \le r_{n - 1} < r_{n - 1} \\ r_{n - 1} = q_{n + 1}r_n, \end{cases} \]

因为最大公因数是 \(d\),所以 \(r_n = d\),根据倒数第二个等式,那么:

\[d = r_n = r_{n - 2} - q_nr_{n - 1} \]

根据倒数第三个等式:

\[r_{n - 1} = r_{n - 3} - q_{n - 1}r_{n - 2} \]

带入上式:

\[\begin{aligned} d &= r_{n - 2} - q_n(r_{n - 3} - q_{n - 1}r_{n - 2}) \\ &= (1 + q_nq_{n - 1})r_{n - 2} - q_nr_{n - 3} \end{aligned} \]

以此类推,逐步消去 \(r_{n - 2}, r_{n - 3}, \dots\),可以得到:

\[d = xa + yb \]

证毕。
:::
::::

首先,使用 exgcd 求出 \(ax + by = \gcd(a, b)\) 的解,记为 \(x_0, y_0\),则有:

\[a\frac{x_0c}{\gcd(a, b)} + b\frac{y_0c}{\gcd(a, b)} = c \]

显然,我们找到了原方程的一组特解 \(x_1 = \frac{x_0c}{\gcd(a, b)}, y_1 = \frac{y_0c}{\gcd(a, b)}\)

我们设 \(a(x_1 + m) + b(y_1 + n) = c\),考虑怎么求出 \(m, n\)

将式子展开可以发现,需要让 \(am + bn = 0\)

我们让 \(m = t \times \frac{b}{\gcd(a, b)}, n = t \times \frac{a}{\gcd(a, b)}(t \in \mathbb{Z})\),带入发现 \(am + bn = 0\),于是通解为:

\[\begin{cases} x = x_1 + t \times \frac{b}{\gcd(a, b)} \\ y = y_1 - t \times \frac{a}{\gcd(a, b)} \end{cases} \]

\(x\) 最小值

显然,我们要找出最小的 \(t\) 使得 \(x \ge 1\)

\[x \ge 1 \\ x_1 + t \times \frac{b}{\gcd(a, b)} \ge 1 \\ t \times \frac{b}{\gcd(a, b)} \ge 1 - x_1 \\ t \ge \left\lceil \frac{1 - x_1}{\frac{b}{\gcd(a, b)}} \right\rceil \]

显然可以直接求。

\(y\) 最大值

根据 \(ax + by = c\),可得 \(y = \frac{c - ax}{b}\)

注意到 \(y\)\(\mathbb{R}\) 上单调递减,\(x\) 取到 \(x_{\min}\) 再求出 \(y_{\max}\) 即可。

如果 \(y_{\max} \le 0\),就没有正整数解。

\(y\) 最小值

考虑 \(ax_{\max} + by_{\min} = c\) 这个方程。

由于 \(ax_{\min} + by_{\max} = c\),设 \(\Delta x = x_{\max} - x_{\min}, \Delta y = y_{\min} - y_{\max}\)

得:

\[\begin{cases} \Delta x = t \times \frac{b}{\gcd(a, b)} \\ \Delta y = -t \times \frac{a}{\gcd(a, b)} \end{cases} \]

根据

\[\begin{aligned} y_{\min} &= \Delta y + y_{\max} \\ &= y_{\max} - t \times \frac{a}{\gcd(a, b)} \end{aligned} \]

说明

\[y_{\min} \equiv y_{\max} \pmod{\frac{a}{\gcd(a, b)}} \]

由于 \(y_{\min}\) 必须是最小正整数,得:

\[y_{\min} = \begin{cases} y_{\max} \bmod \frac{a}{\gcd(a, b)}, & y_{\max} \bmod \frac{a}{\gcd(a, b)} \ne 0 \\ \frac{a}{\gcd(a, b)}, & y_{\max} \bmod \frac{a}{\gcd(a, b)} = 0 \end{cases} \]

\(x\) 最大值

\(y_{\max}\) 一样,把 \(y_{\min}\) 代入即可。

解的个数

我们在 \((y_{\min}, y_{\max}]\) 中寻找解。

考虑变换一下通解格式:

\[\begin{cases} x' = y - t \times \frac{b}{\gcd(a, b)} \\ y' = x + t \times \frac{a}{\gcd(a, b)} \end{cases} \]

显然,每隔 \(\frac{a}{\gcd(a, b)}\) 个就会存在一个解,那么解的个数为 \(\frac{y_{\max} - y_{\min}}{\frac{a}{\gcd(a, b)}} + 1\)

对于正无整数解的情况,也是类似的。

::::success[code]

while (T--) {
    int a, b, c;
    cin >> a >> b >> c;
    exgcd(a, b);
    int qwq = __gcd(a, b);
    if (c % qwq) {
        cout << "-1\n";
        continue;
    }
    x = x * c / qwq;
    y = y * c / qwq;
    int X = b / qwq, Y = a / qwq;
    int awa = ceil((1.0 - x) / X);
    x += X * awa;
    y -= Y * awa;
    if (y <= 0) {
        int y_min = y + Y * ceil((1.0 - y) / Y);
        cout << x << ' ' << y_min << '\n';
    }
    else cout << (y - 1) / Y + 1 << ' ' << x << ' ' << (y - 1) % Y + 1 << ' ' << x + (y - 1) / Y * X << ' ' << y << '\n';
}

::::

posted @ 2026-07-15 15:06  Loyal_Soldier  阅读(21)  评论(0)    收藏  举报