题目:
求关于x的同余方程ax≡1(modb)的最小正整数解。
输入格式
输入只有一行,包含两个正整数a,b,用一个空格隔开。
输出格式
输出只有一行,包含一个正整数x,表示最小正整数解
答案:
#include <iostream>
using namespace std;
typedef long long LL;
LL a, b, x, y;
LL exgcd(LL a, LL b, LL &x, LL &y) // 扩展欧几里得算法, 求x, y,使得ax + by = gcd(a, b)
{
if (!b)
{
x = 1; y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= (a / b) * x;
return d;
}
int main()
{
cin >> a >> b;
exgcd(a, b, x, y);
cout << (x % b + b) % b;
return 0;
}
题解:
为了找到 x,我们首先需要确保 a 和 b 互素(即 gcd(a,b)=1),因为只有在这种情况下,模反元素才存在。对于 ax≡1(modb)来说,存在唯一 x 满足这个方程。因此,可以直接x=((x%b+b)%b)
对于另外一种情况:如果同余方程的一般形式是 ax≡c(modb),其中 c 不是 1,那么需要找到一个 x 满足这个方程。我们可以使用以下步骤来求解:
-
求解方程 ax≡c(modb):
首先,确保 gcd(a,b)能整除 c。如果不能整除,那么方程没有解。使用扩展欧几里得算法找到初步解使得 ax0≡gcd(a,b)(modb)。 -
调整初步解:
假设 gcd(a,b)=d,则我们有 ax0≡d(modb)。因此,方程 ax≡c(modb) 的解可以通过调整初步解得到。设 c=kd,则方程可以写成 a(kx0)≡c(modb)。 即x*=c/d -
求解最终解:
求出初步解 x0后,最终解为 x=kx0。将 x 转换为最小正整数解,使用 x=((x%b+b)%b)。