您的位置:首页 > 其它

gcd欧几里德算法/extgcd扩展欧几里德算法以及在解不定方程中的应用

2017-03-19 21:10 288 查看
这个应该是我在noip前就应该会的东西 ,但是当时也许只是记下了代码吧 ,现在有诸多的不理解。后来借着书和几篇博客弄懂了并小证了一下,鉴于网上有些博客关于这个的写的真的不好看,所以自己来总结一下,顺带以后也能看。

顺带一提,gcd(a,b)表示a,b的最大公约数。

欧几里德算法

辗转相除法求最大公约数问题,同可求最小公倍数。

既然是辗转相除法,自然就是%%%,%到互相整除为止。代码也很详尽简洁。

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


最小公倍数为两数之积除以他们的最大公约数,相信大家都能明白。

扩展欧几里德算法

我之前一直困惑的是它为什么可以求不定方程的解,后来基本明白了:

给定一个形如方程ax+by=d,求它的整数解。

我们知道a,b为整数,d是整数,使得x,y为整数解,那么需要约掉系数中相同的部分,于是方程ax+by=d有整数解⇒gcd(a,b)|d

所以说,假设我们有d=gcd(a,b)∗t,则方程ax+by=d的解为agcd(a,b)x+bgcd(a.b)y=gcd(a,b)的t倍,那么原问题转化为求方程agcd(a,b)x+bgcd(a.b)y=gcd(a,b)的解了。

再推到一般,若a,b互质,有ax+by=1有解。

然后接下来我们考虑特殊解的情况:

gcd(a,b)递归的最终结果为gcd(k,0),假定方程有解,那么最终有a∗1+b∗0=gcd(a,b),即a∗1+b∗0=1,即x=1, y=0出现,这是在求gcd时递归形成的。若我们也这样地求解方程呢?

于是我们来找ax+by=gcd(a,b)与bx′+(a%b)∗y′=gcd(b,a%b)的关系,由于a%b=a−(a/b)∗b(整数除法) 所以代入有ay′+b(x′−a/b∗y′)=gcd(a,b)=gcd(b,a%b)

于是原方程解为x=y′,y=x′−(a/b)∗y′。

这样我们就能递归地计算方程的解了。

int extgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
int ans;
ans=extgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-(a/b)*y;
return ans;
}
}


不定方程不是有很多解吗?是的,这只是最小解。设最小解为x0,y0,它的所有解为x=x0+bgcd(a,b)和y=y0+agcd(a,b)。(自己带到方程里展开就有恒等式,这里不证了)当gcd(a,b)=1时,有x=x0+b,y=y0+a。

while(x<=0)
{
x+=(b/res);
}
printf("%d\n",x);


例题:zoj3609求逆元

方法同上,AC代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
//zoj3609 AC
using namespace std;

int extgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a; } else { int ans; ans=extgcd(b,a%b,x,y); int tmp=x; x=y; y=tmp-(a/b)*y; return ans; } }

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

int main()
{
int a,b;
int cas;
scanf("%d",&cas);
for(int z=0;z<cas;z++)
{
scanf("%d%d",&a,&b);
int x,y;
if(regulargcd(a,b)==1)
{
int res=extgcd(a,b,x,y);
if(x>0)
{
printf("%d\n",x);
}
else
{
while(x<=0)
{
x+=(b/res);
}
printf("%d\n",x);
}
}
else
{
printf("Not Exist\n");
}
}
return 0;
}


关于逆元,请移步逆元-wiki

谢谢看到这里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: