扩展欧几里得求线性同余方程

文章介绍了如何使用C++编程语言实现欧几里得算法(GCD),解决求解两个整数a和m的最大公约数以及找到满足b模t等于0的x值的问题。

```cpp

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int exgcd(int a, int b, int& x, int& y){
    if(!b){
        x = 1, y = 0;
        return a;
    }
    
    int d = exgcd(b,a % b,x,y);
    int tx = x,ty = y; //存一下当前层的数据,防止前面计算影响
    x = ty;
    y = tx - (a / b) * ty;
    return d;
}
int main(){
    int n;
    cin >> n;
    
    while(n --){
        int a, b, m;
        cin >> a >> b >> m;
        int x, y;
        int t = exgcd(a,m,x,y);
        
        if(b % t){
            puts("impossible");
        }else{
            cout << (long long) x * (b / t) % m << endl;
        }
    }
    
    return 0;
}

```

扩展欧几里得算法可用于解同余方程 \(ax \equiv b \pmod{m}\),以下是具体方法及原理: ### 原理 同余方程 \(ax \equiv b \pmod{m}\) 等价于存在整数 \(y\),使得 \(ax - b = my\),即 \(ax + my = b\)。因此,解同余方程 \(ax \equiv b \pmod{m}\) 就转化为解线性不定方程 \(ax + my = b\) 的整数解 \(x\) 和 \(y\)。 ### 步骤 1. **使用扩展欧几里得算法解 \(ax + my = \gcd(a, m)\) 的一组特解 \(x_0\) 和 \(y_0\)** 扩展欧几里得算法是在欧几里得算法的基础上,不仅出 \(\gcd(a, m)\),还能出满足 \(ax + my = \gcd(a, m)\) 的整数 \(x\) 和 \(y\)。以下是扩展欧几里得算法的代码实现: ```cpp #include <iostream> using namespace std; int exgcd(int a, int b, int &x, int &y) { if (!b) { x = 1, y = 0; return a; } int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } ``` 2. **判断方程是否有解** 方程 \(ax + my = b\) 有解的充要条件是 \(b\) 能被 \(\gcd(a, m)\) 整除,即 \(b \% \gcd(a, m) == 0\)。若不满足该条件,则方程无解。 3. **出 \(ax + my = b\) 的一组特解** 若方程有解,设 \(d = \gcd(a, m)\),则 \(ax + my = b\) 的一组特解 \(x_1\) 和 \(y_1\) 可由 \(ax + my = d\) 的特解 \(x_0\) 和 \(y_0\) 得到: \(x_1 = x_0 \times \frac{b}{d}\) \(y_1 = y_0 \times \frac{b}{d}\) 4. **出同余方程的最小非负整数解** 同余方程 \(ax \equiv b \pmod{m}\) 的通解为 \(x = x_1 + k \times \frac{m}{d}\)(\(k\) 为整数)。为得到最小非负整数解,可对 \(x_1\) 进行如下处理: \(x = (x_1 \% \frac{m}{d} + \frac{m}{d}) \% \frac{m}{d}\) ### 完整代码示例 ```cpp #include <iostream> using namespace std; // 扩展欧几里得算法 int exgcd(int a, int b, int &x, int &y) { if (!b) { x = 1, y = 0; return a; } int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } // 解同余方程 ax ≡ b (mod m) int solveCongruence(int a, int b, int m) { int x, y; int d = exgcd(a, m, x, y); if (b % d != 0) { return -1; // 无解 } int k = b / d; x *= k; m /= d; x = (x % m + m) % m; return x; } int main() { int a, b, m; cin >> a >> b >> m; int result = solveCongruence(a, b, m); if (result == -1) { cout << "无解" << endl; } else { cout << "最小非负整数解为: " << result << endl; } return 0; } ``` ### 复杂度分析 - **时间复杂度**:扩展欧几里得算法的时间复杂度与欧几里得算法相同,为 \(O(\log \min(a, m))\)。 - **空间复杂度**:主要为递归调用栈的空间,空间复杂度为 \(O(\log \min(a, m))\)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值