扩展欧几里得定理

扩展欧几里得定理,很早之前就接触过,没看懂,放弃了,前些天有个有一个题,用扩展欧几里得定理,我竟然都不知道。决定看一下。

看扩展欧几里得定理的最好地方是用维基百科搜索扩展欧几里得算法 就能搜到

照着上面提供第例子走一遍知道什么意思了。

反正主要就是 ax+by=1(mod n) 的x,y值;

还有就是 ax=b(mod n) 这类题的通用解法;

下面粘上一个例子,看完这个例子你就明白了。

poj 1061 青蛙的约会

中文题目,我的最爱。

我们设他们跳的步数为step 那么就可以写出算式 n*step+x=m*step+y (mod L) 我们来整理一下就的到了

(n-m)step=y-x(mod L) 然后再来 向ax+by=c来化简

就成了 (n-m)step+kL=y-x 当且仅当gcd((n-m),L)|(y-x) 时有解 。 |为整除的意思 

至于系数的变化,我们先要两边同除以gcd((n-m),L) 结果不变,然后在同除c来保证方程右边为1;

具体细节在代码中有。

#include<iostream>
#include<stdio.h>
using namespace std;
__int64  gcd(__int64  a,__int64  b)
{
	return b==0? a:gcd(b,a%b);
}
__int64  exgcd(__int64  i,__int64  j,__int64  &ansx,__int64  &ansy)
{
	__int64  d = i;
	if(j==0)
	{
		ansx=1;
		ansy=0;
		return d;
	}
	d=exgcd(j,i%j,ansx,ansy);
	__int64  temp = ansx;
	ansx=ansy;
	ansy=temp-(i/j)*ansy;
	return d;
}
int  main()
{
	__int64  m,n,x,y,l;
	cin>>x>>y>>m>>n>>l;
	
	__int64  a=n-m;
	__int64  b=l;
	__int64  c=x-y;

	__int64  d = gcd(a,b);
	if(c%d!=0)
	{
		cout<<"Impossible"<<endl;
		return 0;
	}
	a/=d;
	b/=d;
	c/=d;
	__int64  ansx,ansy;
	exgcd(a,b,ansx,ansy);
	__int64  t = ansx*c/b;
	ansx = ansx*c-t*b;
	if(ansx<0)
		ansx+=b;
	cout<<ansx<<endl;

}

在这说下扩展欧几里得算法 网上到处都是 。虽然看上去有些绕,但是固定的写法。

好了!

感谢自己坚持。


你可能感兴趣的:(算法,扩展,poj)