扩展欧几里得算法

题目描述

给定n对正整数,对于每对数,求出一组 x i , y i x_i,y_i xi,yi ,使其满足 a i x i + b i y i = g c d ( a i , b i ) a_ix_i+b_iy_i=gcd(a_i,b_i) aixi+biyi=gcd(ai,bi)

输入格式

第一行包含整数n。
接下来n行,每行包含两个整数 a i , b i a_i,b_i ai,bi

输出格式

输出共n行,对于每组 a i , b i a_i,b_i ai,bi,求出一组满足条件的 x i , y i x_i,y_i xi,yi,每组结果占一行。

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

数据范围

1 ≤ n ≤ 1 0 5 1\leq n \leq10^5 1n105
1 ≤ a i , b i ≤ 2 ∗ 1 0 9 1\leq a_i,b_i\leq2*10^9 1ai,bi2109

输入样例
2
4 6
8 18
输出样例
-1 1
-2 1
扩展gcd

用于求解方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b) 的解

b = 0 b=0 b=0 时 , a x + b y = a ax+by=a ax+by=a 故而 x = 1 , y = 0 x=1,y=0 x=1,y=0
b ≠ 0 b≠0 b=0

因为
g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)

b x + ( a % b ) y = g c d ( b , a % b ) bx+(a\%b)y=gcd(b,a\%b) bx+(a%b)y=gcd(b,a%b)
b x + ( a − ⌊ a / b ⌋ ∗ b ) y = g c d ( b , a % b ) bx+(a- \lfloor a/b \rfloor*b)y=gcd(b,a\%b) bx+(aa/bb)y=gcd(b,a%b)
对左边式子展开
a y + b ( x − ⌊ a / b ⌋ ∗ y ) = g c d ( b , a % b ) ay+b(x- \lfloor a/b \rfloor*y)=gcd(b,a\%b) ay+b(xa/by)=gcd(b,a%b)
上下两式对比
a x + b y = g c d ( b , a % b ) ax+by=gcd(b,a\%b) ax+by=gcd(b,a%b)
则有
x = y , y = x − ⌊ a / b ⌋ ∗ y x=y,y=x- \lfloor a/b \rfloor*y x=y,y=xa/by

有了上述结论,我们就可以写代码了

#include<bits/stdc++.h>
using namespace std;
inline int exgcd(int a, int b, int &x, int &y){
    if(b==0){
        x = 1, y = 0;
        return a;
    }
    int x1,y1,d;
    d = exgcd(b, a%b, x1, y1);
    x = y1, y = x1 - a/b*y1;
    return d; 
}
int main(){
    int n,a,b,x,y;
    cin>>n;
    while(n--){
        cin>>a>>b;
        exgcd(a,b,x,y);
        cout<<x<<" "<<y<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值