您的位置:首页 > 其它

poj 1061 扩展欧几里得解同余方程(求最小非负整数解)

2014-11-01 18:33 204 查看
题目可以转化成求关于t的同余方程的最小非负数解:

x+m*t≡y+n*t (mod L)

该方程又可以转化成:

k*L+(n-m)*t=x-y

利用扩展欧几里得可以解决这个问题:

eg:对于方程ax+by=c

设tm=gcd(a,b)

若c%tm!=0,则该方程无整数解。

否则,列出方程:

a*x0+b*y0=tm

易用extend_gcd求出x0和y0

然后最终的解就是x=x0*(c/tm),y=y0*(c/tm)

注意:若是要求最小非负整数解

例如求y的最小非负整数解,

令r=a/tm,则y=(y%r+r)%r;

#include <iostream>
using namespace std;
__int64 x,y,m,n,L;

__int64 extend_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y){
if (b==0){
x=1;y=0;
return a;
}
else{
__int64 r=extend_gcd(b,a%b,y,x);
y=y-x*(a/b);
return r;
}
}

int main()
{
cin>>x>>y>>m>>n>>L;

__int64 k,t;
__int64 tm=extend_gcd(n-m,L,t,k);
if ((x-y)%tm!=0)
cout<<"Impossible"<<endl;
else
{
__int64 ans=t*((x-y)/tm);
__int64 r=L/tm;
ans=(ans%r+r)%r;    //求出最小非负整数解
//while (ans<0)   ans+=k/tm;    //这样做是错的= =
cout<<ans<<endl;
}

return 0;
}


Reference:http://www.cnblogs.com/yueshuqiao/archive/2011/08/23/2150960.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: