自从曹冲搞定了大象以后,曹操就开始琢磨让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲很不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。
举个例子,假如有 16 头母猪,如果建了 3 个猪圈,剩下 1 头猪就没有地方安家了;如果建造了 5 个猪圈,但是仍然有 1 头猪没有地方去;如果建造了 7 个猪圈,还有 2 头没有地方去。
你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?
输入格式
第一行包含一个整数 n,表示建立猪圈的次数;
接下来 n 行,每行两个整数 ai,bi,表示建立了 ai 个猪圈,有 bi 头猪没有去处。
你可以假定 ai,aj 互质。
输出格式
输出仅包含一个正整数,即为曹冲至少养猪的数目。
数据范围
1 ≤ n ≤ 10 , 1 ≤ b i ≤ a i ≤ 1100000 , 所 有 a i 的 乘 积 不 超 过 1 0 18 1≤n≤10, 1≤b_i≤a_i≤1100000 ,所有a_i的乘积不超过 10^{18} 1≤n≤10,1≤bi≤ai≤1100000,所有ai的乘积不超过1018
输入样例:
3
3 1
5 1
7 2
输出样例:
16
分析:
《中国剩余定理》
本题中:
给 定 n 个 条 件 可 列 出 n 个 方 程 : 给定n个条件可列出n个方程: 给定n个条件可列出n个方程:
{ x ≡ b 1 ( m o d a 1 ) x ≡ b 2 ( m o d a 2 ) . . . x ≡ b n ( m o d a n ) , 且 对 任 意 的 i , j ∈ [ 1 , n ] , a i 与 a j 互 质 。 \begin{cases}x≡b_1(mod\ a_1)\\x≡b_2(mod\ a_2)\\...\\x≡b_n(mod\ a_n)\end{cases},且对任意的i,j∈[1,n],a_i与a_j互质。 ⎩⎪⎪⎪⎨⎪⎪⎪⎧x≡b1(mod a1)x≡b2(mod a2)...x≡bn(mod an),且对任意的i,j∈[1,n],ai与aj互质。
即 求 x 的 最 小 正 整 数 解 。 即求x的最小正整数解。 即求x的最小正整数解。
满 足 中 国 剩 余 定 理 使 用 的 前 提 条 件 , 满足中国剩余定理使用的前提条件, 满足中国剩余定理使用的前提条件,
通 解 : 通解: 通解:
x = b 1 M 1 M 1 − 1 + b 2 M 2 M 2 − 1 + . . . + b n M n M n − 1 + k M , x=b_1M_1M_1^{-1}+b_2M_2M_2^{-1}+...+b_nM_nM_n^{-1}+kM, x=b1M1M1−1+b2M2M2−1+...+bnMnMn−1+kM,
其 中 M = ∏ i = 1 n a i , M i = M a i , M i − 1 是 M i 模 a i 的 逆 元 , k ∈ Z 。 其中M=\prod_{i=1}^na_i,M_i=\frac{M}{a_i},M_i^{-1}是M_i模a_i的逆元,k∈Z 。 其中M=∏i=1nai,Mi=aiM,Mi−1是Mi模ai的逆元,k∈Z。
求 M i − 1 : 解 同 余 方 程 M i x ≡ 1 ( m o d a i ) < = > M i x + a i y = 1 求M_i^{-1}:解同余方程M_ix≡1(mod\ a_i)\quad<=>\quad M_ix+a_iy=1 求Mi−1:解同余方程Mix≡1(mod ai)<=>Mix+aiy=1
扩 展 欧 几 里 得 算 法 解 得 x 0 = M i − 1 扩展欧几里得算法解得x_0=M_i^{-1} 扩展欧几里得算法解得x0=Mi−1
最 后 要 求 最 小 正 整 数 解 , 即 将 x 对 M 取 模 , 计 算 最 小 正 余 数 。 最后要求最小正整数解,即将x对M取模,计算最小正余数。 最后要求最小正整数解,即将x对M取模,计算最小正余数。
代码:
#include
#include
#include
#define ll long long
using namespace std;
int n;
ll A[15],B[15];
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) x=1,y=0;
else
{
exgcd(b,a%b,y,x);
y-=a/b*x;
}
}
int main()
{
cin>>n;
ll M=1;
for(int i=0;i<n;i++)
{
cin>>A[i]>>B[i];
M*=A[i];
}
ll res=0;
for(int i=0;i<n;i++)
{
ll Mi=M/A[i];
ll ti,x;
exgcd(Mi,A[i],ti,x);
res+=B[i]*Mi*ti;
}
cout<<(res%M+M)%M<<endl;
return 0;
}