扩展欧几里得算法,线性同余方程
扩展欧几里得算法
裴蜀定理: 对于任意整数a、b,一定存在非零整数x、y使得(a和b的最大公约数)
扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足
求出的x,y并不是唯一的,但是求出一组,就可以求出所有的解
思路
gcd(a,b) = gcd(b,a mod b)
1.当b为0:
gcd(a,0) = a
ax + 0 * y = a 有x = 1,y = 0
2.当b不为0:
gcd(a,b) = gcd(b,a mod b)
有 by + a%b * x = gcd(b,a mod b)
整理得
x没有变,y变成了y-a/b * x
代码
#include<iostream>
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 = y - a/b * x;
return d;
}
int main()
{
int n;
scanf("%d",&n);
while(n --)
{
int a,b;
scanf("%d%d",&a,&b);
int x,y;
exgcd(a,b,x,y);
printf("%d %d\n",x,y);
}
return 0;
}
线性同余方程
则一定存在y 使得
所以
不妨让 y' = -y
则有 ,当然b能整除gcd(a,m)此方程才有解(即b为a和m的最大公约数的倍数)
此时根据扩展欧几里得算法那求解,事实上求出的是ax + my' = d中的x,让等式右边变成b就把x扩大b/d倍即可(两边同时乘b/d,右边就变成了b)
如果b不能整除gcd(a,m),就输出无解
如果b可以整除gcd(a,m),用扩展欧几里得算法求x,最后结果为x*b/d % m
,d为gcd(a,m),%m是为了保证最后答案在int范围内
代码
#include<iostream>
using namespace std;
typedef long long LL;
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 = y - a/b * x;
return d;
}
int main()
{
int n;
scanf("%d",&n);
while(n --)
{
int a,b,m;
scanf("%d%d%d",&a,&b,&m);
int x, y;
int d = exgcd(a,m,x,y);
if(b % d != 0) puts("impossible"); // 不能整除,无解
else printf("%d\n",(LL)b/d * x % m);
}
return 0;
}
rds_blogs
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具