数学知识2.2-拓展欧几里得算法

一、简述

记录有关拓展欧几里得算法。

二、拓展欧几里得算法

裴蜀定理:若 a,b 是整数,且 ab 的最大公约数 gcd(a,b)=d,那么任意的整数 x,yax+by 一定是 d 的整数倍。特别地,一定存在整数 x,y 使得 ax+by=d

对于任意的 a,bZgcd(a,b)=d,则关于 x,y 的线性丢番图方程(裴蜀等式):ax+by=m,有整数解 (x,y) 当且仅当 md 的倍数。裴蜀等式有解时必然存在无穷多解(例如:ax+by=m,则 (xkbm,y+kam)k 为整数)。

裴蜀定理的一个重要推论:ab 互质的充要条件是存在整数 (x,y) 使得 ax+by=1

拓展欧几里得算法:对正整数 a,b,有整数解 (x,y),使其满足 ax+by=gcd(a,b)
求解思路如下:
① 若 b=0,则 gcd(a,b)=a,则可取 x=1,y=0 使得 ax+by=gcd(a,b)=a
② 若 b0,则 ax+by=gcd(a,b)=gcd(b,a%b)=d。而 bx+(a%b)y=gcd(b,a%b)=d,而 a%b=aab·b,那么就可以得到 bx+(aab·b)y=d=ax+by,展开得到 ay+b(xab·y)=ax+by,等价得到 ax+b(yab·x)=ax+byx=x,y=yab·x

模板题AcWing 877. 扩展欧几里得算法

题目描述

给定 n 对正整数 ai,bi,对于每对数,求出一组 xi,yi,使其满足 ai×xi+bi×yi=gcd(ai,bi)

输入格式

第一行包含整数 n
接下来 n 行,每行包含两个整数 ai,bi

输出格式

输出共 n 行,对于每组 ai,bi,求出一组满足条件的 xi,yi,每组结果占一行。
本题答案不唯一,输出任意满足条件的 xi,yi 均可。

数据范围

1n105,1ai,bi2×109

输入样例
2
4 6
8 18
输出样例
-1 1
-2 1
C++代码
#include <bits/stdc++.h>
using namespace std;

int n;

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;
}

int main()
{
    scanf("%d", &n);
    while(n --)
    {
        int a, b, x, y;
        scanf("%d%d", &a, &b);
        exgcd(a, b, x, y);
        printf("%d %d\n", x, y);
    }
    return 0;
}

三、线性同余方程

axb(modm) 的方程。此方程有解当且仅当 b 能够被 am 的最大公约数整除,记作 gcd(a,m)|b。这时,如果 x0 是方程的一个解,那么所有的解可以表示为:
{x0+knd|(kz)},其中 dam 的最大公约数。在模 m 的完全剩余系 {0,1,,n1} 中,恰有 d 个解。
axb(modm),则存在整数 y 使得 ax=my+b,即 axmy=b,那么由裴蜀定理可知 bgcd(a,m) 的倍数时才有整数解。

模板题AcWing 878. 线性同余方程

题目描述

给定 n 组数据 ai,bi,mi,对于每组数求出一个 xi,使其满足 ai×xibi(modmi),如果无解则输出 impossible

输入格式

第一行包含整数 n
接下来 n 行,每行包含一组数据 ai,bi,mi

输出格式

输出共 n 行,每组数据输出一个整数表示一个满足条件的 xi,如果无解则输出 impossible
每组数据结果占一行,结果可能不唯一,输出任意一个满足条件的结果均可。
输出答案必须在 int 范围之内。

数据范围

1n105,1ai,bi,mi2×109

输入样例
2
2 3 6
4 3 5
输出样例
impossible
-3
C++代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int n;

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;
}

int main()
{
    scanf("%d", &n);
    while(n --)
    {
        int a, b, m, x, y;
        scanf("%d%d%d", &a, &b, &m);
        int d = exgcd(a, m, x, y);
        if(b % d) puts("impossible");
        else printf("%d\n", (LL)b / d * x % m);
    }
    return 0;
}
posted @   Cocoicobird  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示