数论专题-中国剩余定理
本篇博客是【数论专题】系列的第 \(9\) 篇,希望大家多多支持。
中国剩余定理用来求解以下同余方程组:
\[\begin{cases}
x\equiv a_1&\pmod {b_1}\\
x\equiv a_2&\pmod {b_2}\\
\dots\\
x\equiv a_n&\pmod {b_n}
\end{cases}
\]
其中 \(b_i\) 两两互质。
根据余数的可加性,只有求出以下 \(n\) 个方程组的解,则可以求出原方程的解:
\[\begin{cases}
x_1\equiv a_1&\pmod {b_1}\\
x_1\equiv 0&\pmod {b_2}\\
\dots\\
x_1\equiv 0&\pmod {b_n}
\end{cases}
\begin{cases}
x_2\equiv 0&\pmod {b_1}\\
x_2\equiv a_2&\pmod {b_2}\\
\dots\\
x_2\equiv 0&\pmod {b_n}
\end{cases}
\dots
\begin{cases}
x_n\equiv 0&\pmod {b_1}\\
x_n\equiv 0&\pmod {b_2}\\
\dots\\
x_n\equiv a_n&\pmod {b_n}
\end{cases}
\]
原方程解 \(x = \sum^{n}_{i = 1} x_i\)。
设当前求解的方程组为第 \(c\) 个:
\[\begin{cases}
x_c\equiv 0&\pmod {b_1}\\
x_c\equiv 0&\pmod {b_2}\\
\dots\\
x_c\equiv a_c&\pmod {b_c}\\
\dots\\
x_c\equiv 0&\pmod {b_n}
\end{cases}
\]
将上方程组转化为:
\[\begin{cases}
y_c\equiv 0&\pmod {b_1}\\
y_c\equiv 0&\pmod {b_2}\\
\dots\\
y_c\equiv 1&\pmod {b_c}\\
\dots\\
y_c\equiv 0&\pmod {b_n}
\end{cases}
\]
那么,\(x_c = y_c\times a_c\)。
由于 \(b_i\) 两两互质,可得 \(y_c\bmod\ \frac{\prod_{i = 1}^{n} b_i}{b_c} = 0\)。设 \(\frac{\prod_{i = 1}^{n} b_i}{b_c}\) 为 \(l_c\),则 \(b_c = l_c\times w_c\)。
根据以上方程组,可知 \(l_c\times w_c\equiv 1\pmod {b_c}\),显然 \(w_c\) 就是 \(l_c\) 的逆元,直接使用扩展欧几里得算法求就行了。
方程解 \(x = \sum_{i = 1}^{n} a_c\times l_c\times l_c^{-1}\)。
由于需要求的是方程的最小正整数解,需要累加 \(\prod_{i = 1}^{n} a_i\) 并取模。
void exgcd(int a, int b)//扩展欧几里得算法模板
{
if(b == 0)
{
x = 1, y = 0;
return;
}
exgcd(b, a % b);
int tmp = x;
x = y;
y = tmp - a / b * y;
}
for(int i = 1;i <= n;i ++)
{
int qwq = cj / a[i];//cj 为所有数的乘积,qwq 即为 l_c
exgcd(qwq, a[i]);//求出逆元
ans = (ans + qwq * b[i] * x) % cj;//ans 为最终答案
}
cout << (ans + cj) % cj;//转化成最小正整数解

浙公网安备 33010602011771号