先贴出扩展欧几里得算法的代码
#include <iostream>
#define ll long long
using namespace std;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x = 1;
y = 0;
return a;
}
ll d = ex_gcd(b,a%b,x,y);
ll t = x;
x = y;
y = t - a / b * y;
return d;
}
void solve(ll a,ll b,ll c)
{
ll x,y;
ll d = ex_gcd(a,b,x,y);
if(c % d || !a)
{
cout << "Impossible" << endl;
return;
}
x = x * c / d;
**ll t = b / d;
if(t < 0)
{
t = -t;
}
x = (x % t + t)%t;**
cout << x << endl;
return;
}
solve函数中对x结果做出了处理:为求得x的最小正整数解,先是设了t = b/d(即b/gcd),gcd不保证为正,所以如果t为负将它取为正。最后对x做出处理,先把x对t取模得出最小的解,再将这个值加模取模,将它变为一个正数,即可求得最小正整数的解。
为何用b/gcd来取模?
已知扩展欧几里得中的通解公式:
(x1,y1)是一组通解。由此可见,对于这个方程,x的解的周期为b/gcd,y的解的周期为a/gcd。用任意解 x 对 b/gcd 取模,能够得到的是最小解。再对这个解取正,即是最小正整数解。
求y最小正整数解同理,t = a/gcd。