扩展欧几里得

扩展欧几里得算法试求gcd(a,b)的一个非常高效的算法,具体内容是gcd(a,b)=gcd(b,a%b)。它可以再log时间内求出结果。
什么是扩展欧几里得?
考虑一个问题,如果我们知道a和b的最大公约数c,现在需要求出a*x+b*y=c的通解。这该怎么办?
不难看出通解形式一定是
x=x0+(b/c)*t,y=y0-(a/c)*t。那么该如何求出x0和y0?
首先不难看出x=1,y=0这一特解,我们要考虑的是能否通过这一特解推出结果。
根据欧几里得算法,再求gcd(a,b)时已经的出gcd(b,a%b),那么一定有b*x1+(a%b)*y1=c。
对与这一等式可以转化为:b*x1+(a-a/b*b)*y1=c  ==>  a*y1+b(x1-a/b*y1)=c。很明显 x0=y1,y0=x1-(a/b)*y1。

因此可以通过一个递归程序实现,对于每次递归 xn=xn+1,yn=xn+1-(a/b)*yn+1。

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxm = 100005;
int e_gcd(int a, int b, int &x, int &y)
{
	if (b == 0)
	{
		x = 1, y = 0;
		return a;
	}
	int ans = e_gcd(b, a%b, x, y);
	int temp = x;
	x = y;
	y = temp - (a / b)*y;
	return ans;
}
int main()
{
	int n, i, j, k, sum, a, b, x, y;
	while (scanf("%d%d", &a, &b) != EOF)
	{
		k = e_gcd(a, b, x, y);
		printf("%d %d %d\n", k, x, y);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值