1 条题解

  • 0
    @ 2025-10-26 12:30:04

    题目分析

    本题要求解线性同余方程 ax1(modb)ax \equiv 1 \pmod{b},其中 aabb 是给定的正整数,且保证有解(即 gcd(a,b)=1\gcd(a,b) = 1)。

    解题思路

    这个方程实际上是在求 aa 在模 bb 意义下的乘法逆元 xx,即 xa1(modb)x \equiv a^{-1} \pmod{b}。由于题目保证 gcd(a,b)=1\gcd(a,b) = 1,因此可以使用扩展欧几里得算法求解。

    扩展欧几里得算法原理

    扩展欧几里得算法用于求解方程 ax+by=gcd(a,b)ax + by = \gcd(a,b)。当 gcd(a,b)=1\gcd(a,b) = 1 时,方程变为 ax+by=1ax + by = 1。对两边同时取模 bb,得到 ax1(modb)ax \equiv 1 \pmod{b}。因此,我们求得的 xx 就是原方程的解。

    算法步骤

    1. 使用扩展欧几里得算法求出 ax+by=1ax + by = 1 的一组解 (x0,y0)(x_0, y_0)
    2. 由于解不唯一,需要将 x0x_0 调整到最小正整数解:x=(x0modb+b)modbx = (x_0 \bmod b + b) \bmod b

    代码实现分析

    #include <bits/stdc++.h>
    using namespace std;
    
    int exgcd(int a, int b, int &x, int &y) {
        if (b == 0) {
            x = 1;
            y = 0;
            return a;
        }
        
        int d = exgcd(b, a % b, y, x);
        y -= (a / b) * x;
        return d;
    }
    
    int main() {
        int a, b, x, y;
        cin >> a >> b;
        exgcd(a, b, x, y);
        cout << ((x % b) + b) % b; // 求ax+by=1的最小x正整数解
        return 0;
    }
    

    代码解析

    • exgcd函数:递归实现扩展欧几里得算法

      • 基准情况:当 b=0b = 0 时,x=1x = 1y=0y = 0,返回 aa
      • 递归调用:计算 gcd(b,amodb)\gcd(b, a \bmod b),同时交换 xxyy 的位置
      • 更新公式:y=ya/b×xy = y - \lfloor a/b \rfloor \times x
    • 主函数

      • 读入 aabb
      • 调用 exgcd 求解 ax+by=1ax + by = 1
      • 输出最小正整数解:((xmodb)+b)modb((x \bmod b) + b) \bmod b

    复杂度分析

    • 时间复杂度O(logmin(a,b))O(\log \min(a,b)),扩展欧几里得算法的时间复杂度与欧几里得算法相同
    • 空间复杂度O(logmin(a,b))O(\log \min(a,b)),递归调用栈的深度

    示例验证

    对于样例输入:3 10

    扩展欧几里得算法求解过程:

    • 求解 3x+10y=13x + 10y = 1
    • 求得 x=7x = 7y=2y = -2
    • 验证:3×7=211(mod10)3 \times 7 = 21 \equiv 1 \pmod{10}

    输出:7

    总结

    本题是经典的数论问题,核心在于理解扩展欧几里得算法的原理和应用。通过求解贝祖等式 ax+by=gcd(a,b)ax + by = \gcd(a,b),当 gcd(a,b)=1\gcd(a,b) = 1 时,得到的 xx 就是 aa 在模 bb 意义下的逆元,再通过模运算调整即可得到最小正整数解。

    • 1

    信息

    ID
    4150
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者