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;
Reference:http://www.cnblogs.com/yueshuqiao/archive/2011/08/23/2150960.html
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
相关文章推荐
- 扩展欧几里得求最小非负整数解 (POJ 1061 青蛙约会为例)
- poj 1061 扩展欧几里得求解同余方程
- poj1061青蛙的约会【扩展欧几里得求最小解】
- POJ 1061 && POJ 2142 两道扩展欧几里得简单题
- POJ 1061 扩展欧几里得
- POJ 1061 青蛙的约会( 扩展欧几里得)
- POJ 2142 The Balance 求|x|+|y|最小(扩展欧几里得)
- poj 1061 扩展欧几里得
- Poj 1061 青蛙的约会(扩展欧几里得解线性同余式)
- (Relax 数论1.6)POJ 1061 青蛙的约会(扩展的欧几里得公式)
- POJ 1061青蛙的约会(扩展的欧几里得)
- poj 1061 扩展欧几里得
- Poj 1061 青蛙的约会(扩展欧几里得解线性同余式)
- POJ 2142 The Balance 扩展欧几里得,求|x|+|y|最小
- poj 1061 青蛙的约会 数论 扩展欧几里得 commemorate the feelings of me
- poj1061 扩展欧几里得解不定式
- poj 1061青蛙的约会(扩展欧几里得)
- (Relax 数论1.6)POJ 1061 青蛙的约会(扩展的欧几里得公式)
- poj 1061 青蛙的约会(扩展欧几里得)
- POJ 1061 青蛙的约会(扩展欧几里得)