#tYybttg060404. 1634:【例 4】曹冲养猪
1634:【例 4】曹冲养猪
1634:【例 4】曹冲养猪
题目描述
自从曹冲搞定了大象以后,曹操就开始琢磨让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲很不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。
举个例子,假如有 头母猪,如果建了 个猪圈,剩下 头猪就没有地方安家了;如果建造了 个猪圈,但是仍然有 头猪没有地方去;如果建造了 个猪圈,还有 头没有地方去。你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?
输入格式
第一行包含一个整数 ,表示建立猪圈的次数;
接下来 行,每行两个整数 ,表示建立了 个猪圈,有 头猪没有去处。你可以假定 互质。
输出格式
输出仅包含一个正整数,即为曹冲至少养猪的数目。
样例
样例输入 #1
3
3 1
5 1
7 2
样例输出 #1
16
样例解释 #1
- 组条件:
- 求最小的正整数 满足以上同余方程组。
- 解为 (因为 ,,)。
数据范围
对于全部数据:
- 保证 两两互质
时空限制
- 时间限制:1000 ms
- 内存限制:524288 KB
注意:本题是中国剩余定理(Chinese Remainder Theorem, CRT)的模板题。给定同余方程组:
$$\begin{cases} x \equiv b_1 \pmod{a_1} \\ x \equiv b_2 \pmod{a_2} \\ \cdots \\ x \equiv b_n \pmod{a_n} \end{cases}$$其中 两两互质,求最小的正整数解 。
解法:
- 计算 。
- 对于每个 ,计算 。
- 计算 在模 下的逆元 (即 )。
- 则解为 。
- 最小正整数解为 ,如果结果为 则取 (但题目保证有正整数解,且 ,所以 应该大于 )。
由于 较小,且 ,可以直接用扩展欧几里得算法求逆元。注意 可能很大(最大 会溢出),但题目只要求输出最小正整数解,且 ,, 可能超过 long long 范围?实际上 ,远远超过 long long。但中国剩余定理计算过程中需要用到 的乘积,可能溢出。但我们可以使用逐步合并法来避免大数运算。
逐步合并法: 设有两个同余方程:
其中 。则合并后的解为:
其中 满足 。由于 ,可以解出 (用扩展欧几里得求 模 的逆元,然后 )。然后合并后的模数为 ,余数为 (取模 )。依次合并所有方程,最终得到解。
这样每一步的模数和余数都在 long long 范围内(因为 ,乘积最大 ,但逐步合并时,当前模数 不超过已合并的 乘积,当合并到第 个时可能溢出 long long。实际上 远大于 long long,但题目数据可能保证答案在 long long 范围内?样例答案 很小。但为了安全,可以使用高精度或 __int128(如果编译器支持)。由于 ,,乘积最大 ,可以用 __int128 存储。如果不支持 __int128,则需要用高精度。但本题数据较小,可能答案在 long long 范围内,可以直接用 long long,但要注意乘法溢出,可以使用快速乘或 __int128 辅助。
使用中国剩余定理的标准公式时,如果直接用 long long 计算 可能会溢出,所以建议使用逐步合并法,并用 __int128 或高精度。由于 很小,可以手动实现高精度(或使用 Python)。但鉴于 C++ 环境可能不支持 __int128,可以用 long double 或拆分计算,但最稳妥的方法是使用高精度类。考虑到题目难度,数据可能保证答案在 long long 范围内,但未明确说明。我们可以使用逐步合并法,每次合并时用扩展欧几里得求解,并用 __int128 临时计算。