用扩展欧几里得求 ax + by = 1 的特解,再把 x 取模调到最小正整数解。
OJ: roj
题目 ID: 1632
难度:入门
标签:数论扩展欧几里得同余方程
创建: 2026-09-30 23:08
更新: 2026-10-06 01:24
题目描述
求同余方程 3 10,输出 7。
思路
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-30 23:08
# update_at: 2026-09-30 23:08
import sys
def exgcd(a: int, b: int) -> tuple[int, int, int]:
"""扩展欧几里得算法:返回 (g, x, y) 使得 a*x + b*y = g = gcd(a, b)。"""
if b == 0:
return a, 1, 0
g, x1, y1 = exgcd(b, a % b)
return g, y1, x1 - (a // b) * y1
def solve() -> None:
data = sys.stdin.read().split()
if not data:
return
a, b = map(int, data)
_, x, _ = exgcd(a, b)
# 调整为最小正整数解
ans = (x % b + b) % b
print(ans if ans != 0 else b)
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-06 01:24
* update_at: 2026-10-06 01:24
*/
#include <iostream>
typedef long long ll;
// 扩展欧几里得:求出 a*x + b*y = gcd(a, b) 的一组特解 x, y
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
ll g = exgcd(b, a % b, x, y);
ll nx = y;
ll ny = x - (a / b) * y;
x = nx;
y = ny;
return g;
}
int main() {
ll a, b;
std::cin >> a >> b;
ll x, y;
exgcd(a, b, x, y);
// 通解为 x + k*b,把特解调整到 [1, b] 内的最小正整数
ll ans = (x % b + b) % b;
if (ans == 0) {
ans = b;
}
std::cout << ans << std::endl;
return 0;
}