线性同余方程(扩展欧几里得应用)
作者:互联网
线性同余方程(扩展欧几里得算法的应用)
题目内容
给定$n$组数据$a_i, b_i, m_i$, 对于每组数据求出一个$x_i$,使其满足$a_i \times x_i \equiv b_i(mod \ m_i)$
如果无解则输出impossible
输入格式
第一行包含整数 $n$,接下来$n$行,每行包含一组数据$ a_i, b_i, m_i$
输出格式
输出共$n$行, 每行数据输出一个整数表示一个满足条件的 $x_i$,如果无解则输出 impossible
。
每组数据结果占一行,结果可能不唯一,输出任意一个满足条件的结果均可。
输出答案必须在$int$ 范围之内
数据范围
$1 \le n \le 10^5$
$1 \le a_i,b_i,m_i \le 2 \times 10^9$
输入样例
2
2 3 6
4 3 5
输出样例
impossible
-3
一、问题解决
-
把 $ax \equiv b \ \ (mod \ m)$表示$ax - b$为$m$的倍数, 等价为 $ax = my + b$ , 变形可得 $ax-my=b$ .
-
令$y' = -y$,上式变为$ax + my' = b$,即线性同余方程方程等价为$ax + my = b$,
-
判断是否有解(详见第二部分是否有解)
-
运用欧几里得算法求出一组解$x_0, y_0$, 使得$ax_0 + my_0 = gcd(a,m)$ ,但题目本身是求$ax + my = b$,所以两边同时乘以$\frac{b}{gcd(a,m)}$即可,即$x = x_0 \times \frac{b}{gcd(a,b)} % \ m$
二、是否有解
引入一个定理:裴蜀定理(贝祖定理):
设$a,b$不全为零的整数,则存在整数$x, y$使得$ax + by = gcd(a, b)$
关于定理的证明
: https://oi-wiki.org/math/number-theory/bezouts/
所以由裴蜀定理可知:
-
当$gcd(a,m) \ | \ b$时,方程有解
整除的解释:'|' 整除号,如a|b (a不为0),若存在整数k,使得b=ka,则称a整除b
-
反之,方程无解
三、扩展欧几里得算法
用于求解$ax+by=gcd(a,b)$的解
-
当$b = 0$时,$ax = a$,此时$x = 1, y = 0$
注意: 当a不为0时,gcd(a, 0) = gcd(0, a) = a
-
当$b \neq 0$时,由于$gcd(a, b) = gcd(b, a\ % \ b)$
代入$ax + by = gcd(a, b)$中可联立方程
$$
\begin{aligned}
& ax + by = gcd(a,b) \qquad \qquad \qquad①\
& bx' + (a \ % \ b)y' = gcd(b, a\ % \ b)\ \quad②
\end{aligned}
$$
因为$a % b = a - \lfloor {a/b}\rfloor \times b$,代入整理可得$ay' + b(x' - \lfloor a/b \rfloor \times y') = gcd(b,\ a % \ b) = gcd(a, b)$
所以:
$$
x = y',y = x' - \lfloor a/b \rfloor \times y' \quad ③
$$
所以可以利用递归算法,求出下一层的$x' 与 y'$,递归至边界$b = 0$时,$x = 1, y = 0$
,然后再利用公式③回代即可求解
五、C++代码
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
int n, x, y;
int exgcd(int a, int b, int &x, int &y){//ax + by = gcd(a, b)
if(b == 0){
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, x, y);
int z = x;
x = y;
y = z - a / b * y;
return d;
}
int main(){
cin >> n;
while(n --){
int a, b, m;
cin >> a >> b >> m;
//ax + my = b,传入参数要匹配
int d = exgcd(a, m, x, y);
if(b % d) cout << "impossible\n";
else{
x = (LL)x * b / d % m;
cout << x << endl;
}
}
return 0;
}
标签:输出,gcd,int,欧几里得,times,线性,ax,my,同余 来源: https://www.cnblogs.com/PlayfulBlueMoon/p/16396717.html