线性丢番图方程

线性丢番图方程定理

a,b 是整数且 gcd(a,b)=d. 如果 d 不能整除 c , 那么方程 ax+by=c 没有整数解, 如果d 可以整除 c, 则存在无穷个解. 另外, 如果 (x0,y0) 是方程的一个特解, 那么所有解都可以表示为 :

x=x0+(bd)n,y=y0(ad)n

即: ax+by=c 有解的充分必要条件是 d=gcd(a,b)|c
可借助如下图进行理解

扩展欧几里得算法与线性丢番图的解

求解 ax+by=c 的主要是找到一个特解, 那么 exgcd 的作用就是找到一个特解
其扩展欧几里得算法如下:

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;

};

有时为了简化描述, 把 ax+by=gcd(a,b) 两边除以 gcd(a,b), 得到 cx+dy=1, 其中 c=agcd(a,b), d=bgcd(a,b). cd 是互素的, 则 cx+dy=1 的通解为 x=x0+dn, y=y0cn
具体步骤如下:

例题: P1516 青蛙的约会 - 洛谷

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e6 + 10, mod = 1e9 + 7;

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;

};

signed main()

{

    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    int n, m, x, y, L; cin >> x >> y >> m >> n >> L;

    int a = n - m, b = L, c = x - y;

    if(a < 0) a = -a, c = -c;

    int d = exgcd(a, b, x, y);

    if(c % d != 0) cout << "Impossible" << '\n';

    else cout << ((x * (c / d)) % (L / d) + (L / d)) % (L / d) << '\n';

    return 0;

}
```![](https://img2024.cnblogs.com/blog/3205031/202408/3205031-20240806202623129-592127437.png)
posted @   o-Sakurajimamai-o  阅读(63)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
历史上的今天:
2023-08-06 #888
2023-08-06 Gluon
2023-08-06 树的重心
2023-08-06 通往奥格瑞玛的道路(单源最短路+二分)
-- --
点击右上角即可分享
微信分享提示