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

题目:(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;
}
相关推荐
旖-旎19 分钟前
《LeetCode 646 最长数对链 || LeetCode 1143 最长公共子序列》
c++·算法·leetcode·动态规划
Frostnova丶37 分钟前
(15)LeetCode 189. 轮转数组
数据结构·算法·leetcode
kdxiaojie1 小时前
Linux 驱动研究 —— V4L2 (2)
linux·运维·笔记·学习
Lumos1861 小时前
故障保护与鲁棒性(十七)
算法
阿米亚波1 小时前
【C++ STL】std::list
c++·windows·笔记·stl·list
手写码匠1 小时前
从零实现大模型推理引擎:Continuous Batching 与动态调度系统深度解析
人工智能·深度学习·算法·aigc
wabs6662 小时前
关于单调栈【力扣503.下一个更大元素II的思考】
算法·单调栈
c238562 小时前
下篇:伸缩魔法!进阶吃透可变滑动窗口篇
c++·算法
186******205312 小时前
RuView 新手快速上手与实战指南
算法
txzrxz2 小时前
关于二维/多维前缀和
算法