0%

中国剩余定理

基本应用:求 $n$ 个同余方程 $x \equiv r_i \pmod{m_i}$ 形成的方程组,求最小的 $x$ 。其中 $m_i$ 两两互质。

$\left{\begin{matrix}
x \equiv r_1 \pmod {m_1} \
x \equiv r_2 \pmod {m_2} \
x \equiv r_3 \pmod {m_3} \
\vdots \
x \equiv r_n \pmod {m_n}
\end{matrix}\right.$

设 $M=\textstyle \prod_{i=1}^nm_i,M_i=\dfrac{M}{m_i},M’_i \equiv M_i^{-1} \pmod {m_i}$

则 $x \equiv \textstyle\sum_{i=1}^nr_iM’_iM_i \pmod M$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void exgcd(ll a,ll b,ll &x,ll &y) {
if(!b) x = 1,y = 0;
else {
exgcd(b,a % b,y,x);
y -= x * (a / b);
}
}

ll QuickMul(ll a,ll b,ll MOD) {
ll ans = 0;
while(b){
if(b&1) ans = (ans + a) % MOD;
a = (a + a) % MOD;
b >>= 1;
}
return ans;
}

int A[maxN];
int B[maxN];

ll M = 1;ll ans = 0;

int main() {
int K = read();
for(int i = 1; i<=K; i++) A[i] = read();
for(int i = 1; i<=K; i++) B[i] = read();
for(int i = 1; i<=K; i++) M *= B[i];
for(int i = 1; i<=K; i++) {
ll t = M / B[i];
ll x,y;
exgcd(t,B[i],x,y);
x = (x % B[i] + B[i]) % B[i];
ans = (ans + QuickMul(QuickMul(t,x,M),(A[i]+M)%M,M)) % M;
}
printf("%lld",(ans+M)%M);
return 0;
}