数论-裴蜀定理-扩展欧几里得算法
裴蜀定理
对于任意的整数a、b,都存在一对整数x、y(注意x和y可以是负整数),使得
裴蜀定理的证明
已知
从递归边界回归的过程中,当前存在整数x'和y'满足:
根据
因为
以上证明方法,也称为扩展欧几里得算法。
扩展欧几里得算法模板
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,x,y);
int k = x; //K 为 x'
x = y; //x 为 y'
y = k - a/b*y; //y 为 x' - a/b*y'
return d;
}
求解不定方程
对于方程
设
求不定方程
得到
因为
故存在整数t,使得
由 x, y 的任意性,方程的全部解都可以表示为
求x的最小正整数解,设 ,那么
当
当
举例:青蛙约会 http://poj.org/problem?id=1061
分析:
设青蛙A和青蛙B跳跃了t次后相遇,则相对于起点0,青蛙A总路程为
化解方程为
利用扩展欧几里得算法实现如下:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll x, y, m, n, l, a, b, c, _x, _y;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) { // 边界
x = 1, y = 0;
return a;
}
ll d = exgcd(b, a % b, x, y);
ll k = x; // K 为 x'
x = y; // x 为 y'
y = k - a / b * y; // y 为 x' - a/b*y'
return d;
}
int main() {
scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &l);
a = m - n, b = l, c = y - x;
if (a < 0) { //方便计算gcd(a,b)为正整数,a与c一起变号,k为任意整数,故不考虑k
a = -a, c = -c;
}
ll _eg = exgcd(a, b, _x, _y); //_x可能是负数
if (c % _eg)
puts("Impossible");
else {
ll d = c / _eg, p = b / _eg;
_x = _x * d; //_x不一定是最小正整数解
if (_x > 0) {
printf("%lld\n", _x % p); //相当于_x 减去 t个p 后最小正整数解
} else {
printf("%lld\n", (_x % p + p) % p); //相当于_x 加上 t个p 后最小正整数解
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现