爱思创 181253 同余方程 题解
题目大意
小B: 求关于 \(x\) 的同余方程 \(a x \equiv 1 \pmod {b}\) 的最小正整数解。
小A: \(a \equiv b \pmod{c}\) 意为 \(a\ mod\ c = b\ mod\ c\)
铺垫知识
扩展欧几里得
根据裴蜀定理可得 \(ax+by=d, g = gcd(a, b), g | d\)
扩展欧几里得就是在求最大公因数的基础上多求了一组满足 \(ax+by=gcd(a, b)\) 的 x 和 y的特解。
小B: 代码是
void ex_gcd(long long a, long long b, long long &x, long long &y)//这道题不用求最大公因数,用void类型。因为要传回两个参数,所以直接用&直接改
{
if(b == 0)
{
x = 1;
y = 0;
return;//b=0时的特解
}
ex_gcd(b, a % b, x, y);//将x、y改为ex_gcd(b, a % b)的解
int z = x;
x = y;
y = z - a / b * y;//更改x和y
return;
}
思路
这一道题实际上求的是 \(ax+by=1\) 的解,然后输出x的值,但 \(x\) 不一定是最小正整数解。有可能太大,也有可能是负数。
小A: 那么直接用扩展欧几里得得出 \(ax+by=1\) 的解,然后转换成最小正整数解。
小B: 那怎么转换成最小正整数解呢?
小A: 这依然可以解决,\(x\) 批量地减去或加上 \(b\),依然能保证 \(ax+by=1\)
x = (x % b + b) % b;//括号中取模再加,可以处理负数
完整代码
#include<bits/stdc++.h>
using namespace std;
void ex_gcd(long long a, long long b, long long &x, long long &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
ex_gcd(b, a % b, x, y);
int z = x;
x = y;
y = z - a / b * y;
return;
}
int main()
{
long long a, b, x, y;
cin >> a >> b;
ex_gcd(a, b, x, y);
cout << (x % b + b) % b;
return 0;
}
hello, I'm yuzihang, if you need to copy this, please quote this url: https://www.cnblogs.com/yuzihang/articles/16989245.html

浙公网安备 33010602011771号