题目地址:
https://www.luogu.com.cn/problem/P1082
题目描述:
求关于
x
x
x的同余方程
a
x
≡
1
(
m
o
d
b
)
a x \equiv 1 \pmod {b}
ax≡1(modb)的最小正整数解。
输入格式:
一行,包含两个正整数
a
,
b
a,b
a,b,用一个空格隔开。
输出格式:
一个正整数
x
0
x_0
x0,即最小正整数解。输入数据保证一定有解。
数据范围:
对于
40
%
40\%
40%的数据,
2
≤
b
≤
1
,
000
2 ≤b≤ 1,000
2≤b≤1,000;
对于
60
%
60\%
60%的数据,
2
≤
b
≤
50
,
000
,
000
2 ≤b≤ 50,000,000
2≤b≤50,000,000;
对于
100
%
100\%
100%的数据,
2
≤
a
,
b
≤
2
,
000
,
000
,
000
2 ≤a, b≤ 2,000,000,000
2≤a,b≤2,000,000,000。
即求解 a x + b y = 1 ax+by=1 ax+by=1的所有解 ( x , y ) (x,y) (x,y)中 x x x最小正整数可以是多少。可以用扩展欧几里得算法求出一组解 ( x 0 , y 0 ) (x_0,y_0) (x0,y0),则所有解为 ( x 0 + k b , y 0 − k a ) (x_0+kb, y_0-ka) (x0+kb,y0−ka),那么 x x x可以取到的最小正整数就是 x x x在模 b b b剩余类里最小正代表元。代码如下:
#include <iostream>
using namespace std;
long a, b;
long exgcd(long a, long b, long& x, long& y) {
if (!b) {
x = 1, y = 0;
return a;
}
long d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main() {
scanf("%ld%ld", &a, &b);
long x, y;
exgcd(a, b, x, y);
x = (x % b + b) % b;
printf("%ld\n", x);
}
时空复杂度 O ( log min { a , b } ) O(\log\min\{a,b\}) O(logmin{a,b})。