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

题目:(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;
}
相关推荐
longlongzihan8 分钟前
LeetCode 5. 最长回文子串:从暴力匹配到中心扩展的思维演进
c++·算法·leetcode
waoooqwe11 分钟前
问卷样本真实吗
大数据·数据库·算法·数据分析
苦瓜打怪兽17 分钟前
leetcode 热题100(11. 盛最多水的容器)
python·算法·leetcode
w_zero_one1 小时前
链表(4)
java·数据结构·算法
吠品1 小时前
GitHub 周榜拆解:决策小模型扎堆上位
c语言·开发语言·算法
Ivanqhz1 小时前
MLA、DSA、CSA、HCA
人工智能·算法·机器学习
zhangrelay2 小时前
用ROS2Lyrical实验报告册思路重做蓝桥云课ROS1实验并改进
linux·笔记·学习·ubuntu·机器人
嘎嘎风2 小时前
MiniMind 学习笔记之 07 模型怎么学会猜词(旋钮是怎么被拧动的)
算法·源码阅读
和裕3 小时前
定制纸箱刀模费全解析:费用定义与可减免合作场景
大数据·运维·网络·人工智能·算法
白山编程大哥3 小时前
C语言篇:语法进阶
c语言·数据结构·算法