扩展欧几里得算法,线性同余方程

扩展欧几里得算法

acwing877.扩展欧几里得算法

裴蜀定理: 对于任意整数a、b,一定存在非零整数x、y使得ax+by=(a,b)(a和b的最大公约数)

扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足ax+by=gcd(a,b)

求出的x,y并不是唯一的,但是求出一组x0,y0就可以求出所有的解x=x0b/dk,y=y0+a/dk,kZ

思路

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)
by+(aa/bb)x=gcd(b,amodb)

整理得 ax+b(ya/bx)=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;
}

线性同余方程

acwing878.线性同余方程

axb(modm)
则一定存在y 使得ax=my+b
所以axmy=b
不妨让 y' = -y
则有 ax+my=b ,当然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;
}
posted @   r涤生  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示