扩展欧几里得:
利用扩展欧几里得,解不定方程。对于形如:p * a+ q * b = c <1> 的不定方程(其中a,b,c已知),可以用扩展欧几里得算法求解。对于<1>式,若有解,则一定有:
gcd(a,b) /c = 0;
现以此题为例:( n - m)* t + k * l = x - y;
令 a = n - m;b = x- y;则本题既是求解满足a * t + k * l = b 方程t的最小值,既是求一次同余方程 a*t = b (mod l)的最小正整数解;
其步骤:
<1> 写出方程 a * t + k * l = b ,利用扩展欧几里Ex_EucGcd(Long long a, Long long l, Long long&x, Long long&y),求出最大公约数d;
<2>判断是否有解,既b%d == 0,有解,解存在但不唯一!
<3>这是找最小正整数解:x1 = x*(b/d),则最后的解:(x1%(l/d) + l/d)%(l/d)。
求解最小正整数解参考资料:点击打开链接
扩展欧几里得算法实现有两种,一种是迭代法;另一种是递归,容易理解,和使用!
迭代法:
Long long Ex_EucGcd(Long long n, Long long m, Long long &x, Long long &y) {
Long long x1 = 1, x2 = 0, x3 = n;
Long long y1 = 0, y2 = 1, y3 = m;
while (x3 % y3 != 0) {
Long long d = n / m;
Long long t1, t2, t3;
t1 = x1 - d * y1; t2 = x2 - d * y2; t3 = x3 - d * y3;
x1 = y1; x2 = y2; x3 = y3;
y1 = t1; y2 = t2; y3 = t3;
};
x = y1; y = y2;
return y3;
}
long long Extended_Gcd(long long a, long long b, long long &x, long long &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
long long d = Extended_Gcd(b, a%b, x, y);
long long t = x - a/b * y;
x = y;
y = t;
return d;
}
下面是1061的代码:
#include <iostream>
using namespace std;
long long Extended_Gcd(long long a, long long b, long long &x, long long &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
long long d = Extended_Gcd(b, a%b, x, y);
long long t = x - a/b * y;
x = y;
y = t;
return d;
}
int main()
{
long long x, y, n, m, l;
long long a,b,c;
long long x1,y1;
while(cin>>x>>y>>m>>n>>l)
{
a = n - m;
b = l;
c = x - y;
long long M = Extended_Gcd(n-m, l, x1, y1);
if( (c%M != 0) || (m == n) )
cout<<"Impossible"<<endl;
else
{
long long s;
s = b/M;
x1 = x1 * ( c/M );
x1 = (x1%s + s )%s;
cout<<x1<<endl;
}
}
return 0;
}