题目描述
求关于 x x 的同余方程 的最小正整数解.
算法分析
将同余方程转化为二元一次方程的形式,即由 ax≡1(modb) a x ≡ 1 ( mod b ) 转化为 ax−by=1 a x − b y = 1 。
使用扩展欧几里得算法求解:
当 b=0 b = 0 时要满足 ax−by=gcd(a,b) a x − b y = g c d ( a , b ) ,可得 x=1,y=0 x = 1 , y = 0 。
当 b≠0 b ≠ 0 时, bx0+(amodb)y0=gcd(b,amodb) b x 0 + ( a mod b ) y 0 = g c d ( b , a mod b ) ,将 amodb a mod b 用 a−⌊ab⌋×b a − ⌊ a b ⌋ × b 表示得到 bx0+(a−⌊ab⌋×b)y0=gcd(b,amodb) b x 0 + ( a − ⌊ a b ⌋ × b ) y 0 = g c d ( b , a mod b ) ,化简得 ay0+b(x0−⌊ab⌋×y0)=gcd(b,amodb) a y 0 + b ( x 0 − ⌊ a b ⌋ × y 0 ) = g c d ( b , a mod b ) ,则 x=y0,y=x0−⌊ab⌋×y0 x = y 0 , y = x 0 − ⌊ a b ⌋ × y 0 ,以此递归即可。
实现时可将 x,y x , y 的调用位置互换,以不必使用格外的临时变量。
代码实现
#include <cstdio>
typedef long long int ll;
void exgcd(ll a,ll b,ll &x,ll &y) {
if(b==0) {x=1;y=0;}
else {
exgcd(b,a%b,y,x);
y-=a/b*x;
}
}
int main() {
ll a,b;scanf("%lld%lld",&a,&b);
ll x,y;exgcd(a,b,x,y);
printf("%lld\n",(x%b+b)%b);
return 0;
}