算法笔记·数学·扩展欧几里得算法

题目:(AcWing)

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

输入格式

第一行包含整数 n。

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

输出格式

输出共 n 行,对于每组 ai,bi,求出一组满足条件的 xi,yi,每组结果占一行。

本题答案不唯一,输出任意满足条件的 xi,yi 均可。

数据范围

1≤n≤105,

1≤ai,bi≤2×109

输入样例:
复制代码
2
4 6
8 18
输出样例:
复制代码
-1 1
-2 1

扩展欧几里得:

即求解方程ax+by=gcd(a,b) (a,b的最大公约数)的一种方法

举个简单的栗子:

令a = 5, b = 18,求x,y.

解:3 = 18 - 5*3 #1; 2 = 5 - 3 #2; 1 = 3 - 2 #3;

将式#1#2代入#3,则有1 = (18 - 5*3 )-(5 - (18 - 5*3)) = 18-5*3-5+18-5*3 = 5*(-7) + 18*2

故x = -7,y = 2;

不妨设递推的两层变量为,公约数均为c

有方程,

根据欧几里得算法

cpp 复制代码
int gcd(int a,int b)
{
    if(a%b == 0) return b;
    return gcd(b,a%b);
}

易得,

代入一式得,

对比式二系数,知,

又递推到a%b == 0时,可知除数b即为最大公约数c,0*a + 1*b = c, 即 x = 0 , y = 1。

那么可推得上一层a%b == c,则显然,所以 x = 1, y=-1,符合递推公式。

代码实现:

cpp 复制代码
#include<iostream>
using namespace std;

int exgcd(int a,int b,int& x,int &y)
{
    if(a%b == 0)//当a整除b时,b就是最大公约数
    {
        //根据公式ax+by = gcd(a,b);
        x = 0;
        y = 1;
        return b;
    }
    
    int d = exgcd(b,a%b,x,y);
    int t = x;
    x = y;
    y = t - a/b*y;
    return d;
}

int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        int a,b,x,y;
        cin>>a>>b;
        x = y = 0;
        exgcd(a,b,x,y);
        cout <<x<<" "<<y<<endl;
    }
    return 0;
}
相关推荐
kikikidult1 小时前
Ubuntu20.04运行openmvg和openmvs实现三维重建(未成功,仅供参考)
人工智能·笔记·ubuntu·计算机视觉
一缕猫毛2 小时前
【学习笔记】Linux命令
笔记·学习
_jacobfu2 小时前
Foundry 学习笔记 005
笔记·学习·web3·区块链·智能合约
学不动CV了3 小时前
C语言32个关键字
c语言·开发语言·arm开发·单片机·算法
小屁孩大帅-杨一凡4 小时前
如何解决ThreadLocal内存泄漏问题?
java·开发语言·jvm·算法
HXR_plume4 小时前
【计算机网络】王道考研笔记整理(2)物理层
笔记·计算机网络·考研
快乐点吧4 小时前
【前端】异步任务风控验证与轮询机制技术方案(通用笔记版)
前端·笔记
Y1nhl5 小时前
力扣_二叉树的BFS_python版本
python·算法·leetcode·职场和发展·宽度优先
向阳逐梦7 小时前
PID控制算法理论学习基础——单级PID控制
人工智能·算法
2zcode7 小时前
基于Matlab多特征融合的可视化指纹识别系统
人工智能·算法·matlab