专栏文章

题解:P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

P1495题解参与者 3已保存评论 2

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
2 条
当前快照
1 份
快照标识符
@mipyskkg
此快照首次捕获于
2025/12/03 20:09
3 个月前
此快照最后确认于
2025/12/03 20:09
3 个月前
查看原文

题意简述

我们可以把题意简化成这样:
给定 nn 组非负整数 ai,bia_i, b_i,求方程组的最小整数解。 {xb1(moda1)xb2(moda2)xbn(modan)\begin{cases}x\equiv b_1\pmod{a_1}\\x\equiv b_2\pmod{a_2}\\\dots\\x\equiv b_n\pmod{a_n}\end{cases}

中国剩余定理(CRT)

看标题就知道这题是啥了,那我们来看看这个定理吧。

接下来是这道题的数学部分:
先说定理,上述同余方程组的通解为 xM1N1b1++MnNnbn(modm)x \equiv M_1N_1b_1+ \cdots + M_nN_nb_n \pmod m 其中 m=a1a2anm = a_1a_2\cdots a_n 且对于所有的 i[1,n]i \in [1,n],均有 Mi=maiM_i = \frac{m}{a_i}MiNi1(modmi)M_iN_i \equiv 1 \pmod {m_i}
看起来是不是很晕,没错,接下来我来带大家证明一下。
我们先假设方程通解 xx1+x2+x3++xn(modm)x \equiv x_1 + x_2 + x_3 + \cdots + x_n \pmod {m}
并且由 {xb1(moda1)xb2(moda2)xbn(modan)\begin{cases}x\equiv b_1\pmod{a_1}\\x\equiv b_2\pmod{a_2}\\\dots\\x\equiv b_n\pmod{a_n}\end{cases}
我们希望 xx 的形式为
x\equiv b_1+0+0+\dots+0\pmod{a_1}\\ x\equiv 0+b_2+0+\dots+0\pmod{a_2}\\ x\equiv 0+0+b_3+\dots+0\pmod{a_3}\\ \dots\\ x\equiv 0+0+0+\dots+b_n\pmod{a_n}\\ \end{cases}$$ 这样我们就能保证 $x$ 为原方程的解。 好,我们搞清楚这件事后,来看看这组式子需要满足什么呢? 对于所有的 $0$,保证其对应的那项 $x_i$ 能被对应的模数整除即可,即对于所有的 $i \in [1,n]$,均有
x_i \equiv b_i \pmod {a_i}
x_i \equiv 0 \pmod {M_i}
由于 $(M_i, m_i) = 1$,很容易想到取逆元,我们取 $N_i \equiv M_i^{-1} \pmod {m_i}$ 即可,这时 $x_i \equiv b_iM_iN_i \pmod m$ 就可满足上面的条件。 此时,$x \equiv M_1N_1b_1+ \cdots + M_nN_nb_n \pmod m$,证毕! ---- 蒙了吗?没逝后面还有。下面是编程部分: 题目中已经给出了互质的条件,直接相乘模数即可。我们可以用一个比较巧妙的方法求解,对于所有未满足上面 $x$ 的通解的形式的,我们给最终答案累加上我们要的 $b_iM_iN_i$ 这一项,若满足通解的形式,直接跳过就行。这种情况下一定是最小解。 ```cpp #include<bits/stdc++.h> using namespace std; int a[11], b[11]; int main() { long long tot, ans; int n; cin >> n; for(int i = 1; i <= n; i++) { cin >> a[i] >> b[i]; } ans = b[1];//答案 tot = a[1];//目前已经满足的条件中模数的乘积 for(int i = 2; i <= n; i++) { while(ans % a[i] != b[i]) { ans += tot;//枚举即可 } tot *= a[i]; } cout << ans; } ```

评论

2 条评论,欢迎与作者交流。

正在加载评论...