前置知识:求逆元
中国剩余定理 (Chinese Remainder Theorem, CRT) 可求解如下形式的一元线性同余方程组(其中
n
1
,
n
2
,
n
3
,
.
.
.
,
n
k
n_{1},n_{2},n_{3},...,n_{k}
n1,n2,n3,...,nk 两两互质):
{ x ≡ a 1 ( m o d n 1 ) x ≡ a 2 ( m o d n 2 ) . . . x ≡ a k ( m o d n k ) \left\{\begin{matrix} x\equiv a_{1}(mod\ n_{1})\\ x\equiv a_{2}(mod\ n_{2})\\ ...\\ x\equiv a_{k}(mod\ n_{k}) \end{matrix}\right. ⎩⎪⎪⎨⎪⎪⎧x≡a1(mod n1)x≡a2(mod n2)...x≡ak(mod nk)
算法流程
1、计算所有模数的积M
2、对于第i个方程
a
、
计
算
m
i
=
M
n
i
a、计算m_{i}=\frac{M}{n_{i}}
a、计算mi=niM
b
、
计
算
m
i
在
模
n
i
意
义
下
的
乘
法
逆
元
m
i
−
1
b、计算m_{i}在模n_{i}意义下的乘法逆元m_{i}^{-1}
b、计算mi在模ni意义下的乘法逆元mi−1
c
、
计
算
c
i
=
m
i
×
m
i
−
1
c、计算c_i=m_i\times m_i^{-1}
c、计算ci=mi×mi−1
3、方程组的唯一解为
x
=
∑
i
=
1
k
a
i
c
i
(
m
o
d
M
)
x=\sum_{i=1}^{k}a_ic_i(mod\ M)
x=∑i=1kaici(mod M)
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 110;
int n;
int A[N], B[N];
LL exgcd(LL a, LL b, LL &x, LL &y)
{
if(!b)
{
x = 1, y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
cin >> n;
LL M = 1;
for(int i = 1; i <= n; ++ i)
{
cin >> A[i] >> B[i];
M *= A[i];
}
LL s = 0;
for(int i = 1; i <= n; ++ i)
{
LL m = M / A[i];
LL ti, x;
exgcd(m, A[i], ti, x);
s += B[i] * m * ti;
}
cout << (s % M + M) % M << endl;
return 0;
}