欧几里得算法

欧几里得算法:

对于给定的整数a,b,我们可以在O(logn)的时间里求出它们的最大公约数,即使用著名的欧几里得算法(辗转相除法)解决这个问题。

这个算法基于以下事实:

Gcd( a , b ) = Gcd(b , a%b ) ,当b=0,Gcd=a


扩展欧几里得算法:

由裴蜀定理可得,对于一组整数a,b,存在一组整数x,y,使得 ax+by=gcd(a,b)

所以可以用它来求解二元一次不定方程。

由以上事实可得x,y的一组递推公式:

x=y0 , y=x0-(a/b)*y0

但要注意这里的x,y可能为负,所以在求解模方程时要注意将其化为正数。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)

using namespace std;

int a,b,d,x,y;

int gcd(int x,int y)
{
 return (y==0)?x:gcd(y,x%y);
}

void Exgcd(int a,int b,int &d,int &x,int &y)
{
 if (b==0) {d=a;x=1;y=0;}
 else {Exgcd(b,a%b,d,y,x);y-=(a/b)*x;}
}

int main()
{
 scanf("%d%d",&a,&b);
 printf("%d\n",gcd(a,b));
 Exgcd(a,b,d,x,y);
 printf("%d %d\n",x,y);
 return 0;
}
posted @ 2016-05-10 23:44  Krew  阅读(210)  评论(0)    收藏  举报