扩展欧几里得 基础

先放一下欧几里得(辗转相除法)求最大公约数

int gcd(int a,int b){
    return b == 0 ? a : gcd(b,a % b);
}

学扩展欧几里得之前,先了解一下贝祖定理:
如果a、b是整数,那么一定存在整数x,y使得ax+by=gcd(a,b)。

换句话说In a way,如果ax+by=n有解,那么n一定是gcd(a,b)的若干倍。(可判断一个这样的式子有没有解)

常用 如果ax+by=1有解,那么gcd(a,b)=1
也就是说如果gcd(a,b)!=1 无解…
在gcd的基础上,假设到最后递归到了终点,也就是gcd(b,a%b) a%b=0
a=1, 此时ax+by=1 所以x=1,y=0。
此时递归开始返回,在递归算法中,永远都是先得到下面一个状态的值,我们考虑当前层与下一层的关系
假设这一层 a×x+b×y=gcd(a,b)
那么下一层 b×x1+(a%b)×y1=gcd(b,a%b) 等号右边其实就是1
已知a%b=a-a/b×b 代入
下一层变为 a×y1 + b×(x1 – a/b×y1) = 1
所以x=y1 , y=x1 - a/b×y1
此时此刻,把上面的推导变成代码。

#include<bits/stdc++.h>
#define ll long long
#define T int t;scanf("%d", &t);while(t--)
using namespace std;
int extgcd(int a, int b, int &x, int &y){	//注意x和y要引用
   if(b==0){
       x=1;
       y=0;
       return a;
   }
   int ans=extgcd(b,a%b,x,y);  
   int temp = y;	//临时存y
   y=x-a/b*y;
   x=temp;
   return ans;	//返回最大公约数
}
int main(){
   int x=0,y=0;
   cout<<extgcd(2,3,x,y)<<endl;
   cout<<x<<" "<<y<<endl;
   
   return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值