欧几里得算法
欧几里得算法:
对于给定的整数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;
}

浙公网安备 33010602011771号