gcd欧几里德算法/extgcd扩展欧几里德算法以及在解不定方程中的应用
扫描二维码
随时随地手机看文章
这个应该是我在noip前就应该会的东西 ,但是当时也许只是记下了代码吧 ,现在有诸多的不理解。后来借着书和几篇博客弄懂了并小证了一下,鉴于网上有些博客关于这个的写的真的不好看,所以自己来总结一下,顺带以后也能看。
顺带一提,表示a,b的最大公约数。
欧几里德算法
辗转相除法求最大公约数问题,同可求最小公倍数。
既然是辗转相除法,自然就是%%%,%到互相整除为止。代码也很详尽简洁。
int regulargcd(int x,int y) { return y==0?x:(regulargcd(y,x%y)); }
最小公倍数为两数之积除以他们的最大公约数,相信大家都能明白。
扩展欧几里德算法
我之前一直困惑的是它为什么可以求不定方程的解,后来基本明白了:
给定一个形如方程,求它的整数解。
我们知道为整数,是整数,使得为整数解,那么需要约掉系数中相同的部分,于是
所以说,假设我们有,则方程的解为的t倍,那么原问题转化为求方程的解了。
再推到一般,若互质,有有解。
然后接下来我们考虑特殊解的情况:
递归的最终结果为,假定方程有解,那么最终有,即,即,出现,这是在求时递归形成的。若我们也这样地求解方程呢?
于是我们来找与的关系,由于(整数除法) 所以代入有
于是原方程解为。
这样我们就能递归地计算方程的解了。
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; } }
不定方程不是有很多解吗?是的,这只是最小解。设最小解为,它的所有解为和。(自己带到方程里展开就有恒等式,这里不证了)当时,有,。
while(x<=0) { x+=(b/res); } printf("%dn",x);
例题:zoj3609求逆元
方法同上,AC代码
#include#include#include#include#include#include#include//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;z0) { printf("%dn",x); } else { while(x<=0) { x+=(b/res); } printf("%dn",x); } } else { printf("Not Existn"); } } return 0; }
关于逆元,请移步逆元-wiki
谢谢看到这里