中国剩余定理
中国剩余定理(CRT)用于求形如:
{
x
≡
a
1
(
m
o
d
m
1
)
x
≡
a
2
(
m
o
d
m
2
)
⋯
⋯
x
≡
a
k
(
m
o
d
m
k
)
\begin{cases} x \equiv a_1\ (mod\ \ m_1)\\ x \equiv a_2\ (mod\ \ m_2)\\ \cdots\cdots\\ x \equiv a_k\ (mod\ \ m_k)\\ \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧x≡a1 (mod m1)x≡a2 (mod m2)⋯⋯x≡ak (mod mk)
这样一系列同余方程组的最小非负整数解x。
情况1:模数两两互质
模数
m
1
,
m
2
.
.
.
m
k
m_1,m_2...m_k
m1,m2...mk 两两互质的情况,相对来说比较简单。
我们令:
- M M M表示所有方程组的模的乘积。 M = ∏ i = 1 k m i M=\prod_{i=1}^k m_i M=∏i=1kmi
- M i M_i Mi 表示除第 i 个方程外,其余方程组模的乘积。 M i = M m i M_i=\frac {M}{m_i} Mi=miM
- t i t_i ti 为 M i M_i Mi模 m i m_i mi意义下的逆元。 M i t i ≡ 1 ( m o d m i ) M_it_i\equiv 1\ (mod\ m_i) Miti≡1 (mod mi)
其中 1 ≤ i ≤ k 1\leq i \leq k 1≤i≤k。
从这里我们就可以知道,为什么这种情况需要模数两两互质。因为 M i = M m i M_i=\frac {M}{m_i} Mi=miM, M M M中包含 m i m_i mi这个因子,当模数两两互质时, M i M_i Mi也和 m i m_i mi互质,这样 M i M_i Mi才有 m i m_i mi意义下的逆元。
然后我们可以构造出一个解:
x
=
∑
i
=
1
k
a
i
M
i
t
i
x=\sum_{i=1}^k a_iM_it_i
x=∑i=1kaiMiti
由此,任意解
x
0
x_0
x0即为
x
+
k
∗
M
x+k*M
x+k∗M,最小正整数解
x
m
i
n
=
x
0
%
M
x_{min}=x_0 \ \%\ M
xmin=x0 % M
代码:(洛谷P1495)
#include <cstdio>
#define ll long long int
using namespace std;
int N;
ll a[15], b[15], Mi[15], X, M = 1;
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if(b==0)
{
x = 1; y = 0;
return a;
}
ll r = exgcd(b, a%b, x, y);
ll temp = y;
y = x-(a/b)*y;
x = temp;
return r;
}
int main()
{
scanf("%d", &N);
for(int i=1;i<=N;i++)
{
scanf("%d%d", &a[i], &b[i]);
M *= a[i];
}
for(int i=1;i<=N;i++)
{
Mi[i] = M/a[i];
ll x = 0, y = 0;
exgcd(Mi[i], a[i], x, y); //exgcd求逆元
X += b[i]*Mi[i]*(x<0 ? x+a[i] : x);
}
printf("%lld\n", X%M);
return 0;
}
扩展中国剩余定理
ex-CRT,其实就是考虑上例中,模数两两不一定互质的情况,不知道谁给它取了一个扩展中国剩余定理的名字。模数不互质,就不能用借助逆元的方法了,需要另一种(小学数学)方法。
假设已经求出了前
k
−
1
k-1
k−1 个方程的解
x
k
−
1
x_{k-1}
xk−1,设
M
=
L
C
M
(
a
i
)
M = LCM(a_i)
M=LCM(ai),即
M
M
M 为前
k
−
1
k-1
k−1 个除数的最小公倍数,则:
对于前
k
−
1
k-1
k−1 个方程,都满足
x
k
−
1
+
t
M
≡
a
i
(
m
o
d
b
i
)
x_{k-1}+tM \equiv a_i\ (mod\ b_i)
xk−1+tM≡ai (mod bi)
(
t
∈
Z
)
(t \in Z)
(t∈Z)
即:前
k
−
1
k-1
k−1 个方程,通解为
x
k
−
1
+
t
M
x_{k-1}+tM
xk−1+tM
(
t
∈
Z
)
(t \in Z)
(t∈Z)。
想求得第 k k k 个方程的解,并且同时满足前 k − 1 k-1 k−1 个方程,那么需要使第 k k k 个方程的解,为前 k − 1 k-1 k−1 的方程的通解的同时,也满足第 k k k 个方程。
设第
k
k
k个方程的解
x
k
=
x
k
−
1
+
t
M
x_k=x_{k-1}+tM
xk=xk−1+tM
(
t
∈
Z
)
(t \in Z)
(t∈Z)
将此解代入第
k
k
k 个方程中,可得:
x
k
−
1
+
t
M
≡
a
k
(
m
o
d
b
k
)
x_{k-1}+tM \equiv a_k\ (mod\ b_k)
xk−1+tM≡ak (mod bk)
即:
t
M
≡
a
k
−
x
k
−
1
(
m
o
d
b
k
)
tM \equiv a_k-x_{k-1}\ (mod\ b_k)
tM≡ak−xk−1 (mod bk)
其中:
M
,
a
k
,
x
k
−
1
,
b
k
M, a_k, x_{k-1}, b_k
M,ak,xk−1,bk 都是已知的。
使用exgcd解出这个同余方程,得到 t 的值,然后反代回 x k = x k − 1 + t M ( t ∈ Z ) x_k=x_{k-1}+tM\ (t \in Z) xk=xk−1+tM (t∈Z),就可以得到 x k x_k xk 的值。进行 k 次上述操作,可以得到全部 k 个方程的解。
例题
模数互质模板:洛谷P1495 【模板】中国剩余定理(CRT).
模数不互质模板:洛谷P4777 【模板】扩展中国剩余定理(EXCRT).