78 lines
1.8 KiB
Markdown
78 lines
1.8 KiB
Markdown
|
|
##[$AcWing$ $203$. 同余方程](https://www.acwing.com/problem/content/description/205/)
|
|||
|
|
|
|||
|
|
### 一、题目描述
|
|||
|
|
求关于 $x$ 的同余方程 $ax≡1~(mod~b)$ 的 **最小正整数解**。
|
|||
|
|
|
|||
|
|
**输入格式**
|
|||
|
|
输入只有一行,包含两个正整数 $a,b$,用一个空格隔开。
|
|||
|
|
|
|||
|
|
**输出格式**
|
|||
|
|
输出只有一行,包含一个正整数 $x$,表示最小正整数解。
|
|||
|
|
|
|||
|
|
输入数据保证一定有解。
|
|||
|
|
|
|||
|
|
**数据范围**
|
|||
|
|
$2≤a,b≤2×10^9$
|
|||
|
|
|
|||
|
|
**输入样例**
|
|||
|
|
```cpp {.line-numbers}
|
|||
|
|
3 10
|
|||
|
|
```
|
|||
|
|
**输出样例**
|
|||
|
|
```cpp {.line-numbers}
|
|||
|
|
7
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
><font color='red' size=4><b>样例解读:$3*7\%10=1$,此时$7$是最小正整数解</b></font>
|
|||
|
|
|
|||
|
|
### 二、解题思路
|
|||
|
|
|
|||
|
|
**线性同余方程模板题**
|
|||
|
|
|
|||
|
|
因为题目说一定有解。根据裴蜀定理,线性同余方程 $a*x≡b(mod~ m)$有解,当且仅当$gcd(a,m)|b$ 。
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
回到本题,就是 $gcd(a,b)=1$,对照通用形式$\large ax+my=b$,上面的方程对位改写为 $\large ax+by=1$
|
|||
|
|
|
|||
|
|
<font color='red' size=4><b>解释:
|
|||
|
|
|
|||
|
|
通用式 $a*x≡b(mod~ m) \Leftrightarrow ax+my=b $
|
|||
|
|
|
|||
|
|
本题式 $a*x≡1~(m od~b) \Leftrightarrow ax+by=1$
|
|||
|
|
</b></font>
|
|||
|
|
|
|||
|
|
#### 扩欧解题两步走
|
|||
|
|
- ① 用扩展欧几里得算法求出方程$ax+by=1$的一组解$(x_0,y_0)$
|
|||
|
|
- ② 将 $x_0~mod~b$,转移到 $1\sim b$ 区间内即可
|
|||
|
|
|
|||
|
|
|
|||
|
|
### 三、实现代码
|
|||
|
|
|
|||
|
|
```cpp {.line-numbers}
|
|||
|
|
#include <bits/stdc++.h>
|
|||
|
|
using namespace std;
|
|||
|
|
#define int long long
|
|||
|
|
#define endl "\n"
|
|||
|
|
|
|||
|
|
int exgcd(int a, int b, int &x, int &y) {
|
|||
|
|
if (!b) {
|
|||
|
|
x = 1, y = 0;
|
|||
|
|
return a;
|
|||
|
|
}
|
|||
|
|
int d = exgcd(b, a % b, y, x);
|
|||
|
|
y -= a / b * x;
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
signed main() {
|
|||
|
|
int a, b;
|
|||
|
|
cin >> a >> b;
|
|||
|
|
int x, y;
|
|||
|
|
exgcd(a, b, x, y);
|
|||
|
|
cout << (x % b + b) % b << endl;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
|