中国剩余定理
中国剩余定理是用来解这种模数互质的方程组的
{
x
≡
a
1
(
m
o
d
r
1
)
x
≡
a
2
(
m
o
d
r
2
)
x
≡
a
3
(
m
o
d
r
3
)
.
.
.
.
.
.
x
≡
a
n
(
m
o
d
r
n
)
\left\{ \begin{matrix} x\equiv a_1\pmod{r_1}\\ x\equiv a_2\pmod{r_2}\\ x\equiv a_3\pmod{r_3}\\ ......\\ x\equiv a_n\pmod{r_n} \end{matrix} \right.
⎩
⎨
⎧x≡a1(modr1)x≡a2(modr2)x≡a3(modr3)......x≡an(modrn)
其中 r 1 , r 2 , . . . r n r_1,r_2,...r_n r1,r2,...rn互质。
下面来解释一下中国剩余定理是如何解决这类方程组的。
首先,因为 r 1 , r 2 , . . . r n r_1,r_2,...r_n r1,r2,...rn互质,所以我们可以设 A i = ∏ j ≠ i r j A_i=\prod\limits_{j\not=i}r_j Ai=j=i∏rj,则 A i A_i Ai和 r i r_i ri互质。根据扩展欧几里德定理,可得存在一个整数 c i c_i ci,使 c i ∗ A i % r i = 1 c_i*A_i\%r_i=1 ci∗Ai%ri=1,设 x i = a i ∗ A i ∗ c i x_i=a_i*A_i*c_i xi=ai∗Ai∗ci,则 x i % r i = a i x_i\%r_i=a_i xi%ri=ai。因为 A i A_i Ai是除了 r i r_i ri以外其他 r r r值的最小公倍数,所以 A i A_i Ai模其他r值都为 0 0 0。
对于每一个方程,我们都求出一个 x i x_i xi,然后累加起来,最终的值满足所有的方程。
所以 x = ∑ i = 1 n a i ∗ A i ∗ c i x=\sum\limits_{i=1}^n a_i*A_i*c_i x=i=1∑nai∗Ai∗ci。
通解为 x = ∑ i = 1 n a i ∗ A i ∗ c i + p ∗ ∏ i = 1 n r i x=\sum\limits_{i=1}^n a_i*A_i*c_i+p*\prod\limits_{i=1}^n r_i x=i=1∑nai∗Ai∗ci+p∗i=1∏nri,其中p为任意整数。
例题
code
#include<bits/stdc++.h>
using namespace std;
int n;
long long vt=1,x,y,ans=0,r[15],a[15];
void exgcd(long long c,long long d){
if(d==0){
x=1;y=0;
return;
}
exgcd(d,c%d);
long long t=x;x=y;y=t-c/d*y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&r[i],&a[i]);
vt=vt*r[i];
}
for(int i=1;i<=n;i++){
exgcd(vt/r[i],r[i]);
x=(x%r[i]+r[i])%r[i];
ans=(ans+vt/r[i]*a[i]*x%vt)%vt;
}
printf("%lld",ans);
return 0;
}
扩展中国剩余定理
如果模数互质,则使用中国剩余定理。但如果模数不互质呢?那我们就要使用扩展中国剩余定理了。同样的方程组:
{
x
≡
a
1
(
m
o
d
r
1
)
x
≡
a
2
(
m
o
d
r
2
)
x
≡
a
3
(
m
o
d
r
3
)
.
.
.
.
.
.
x
≡
a
n
(
m
o
d
r
n
)
\left\{ \begin{matrix} x\equiv a_1\pmod{r_1}\\ x\equiv a_2\pmod{r_2}\\ x\equiv a_3\pmod{r_3}\\ ......\\ x\equiv a_n\pmod{r_n} \end{matrix} \right.
⎩
⎨
⎧x≡a1(modr1)x≡a2(modr2)x≡a3(modr3)......x≡an(modrn)
首先取前两个方程:
x = k ∗ r 1 + a 1 = p ∗ r 2 + a 2 x=k*r_1+a_1=p*r_2+a_2 x=k∗r1+a1=p∗r2+a2
k ∗ r 1 − p ∗ r 2 = a 2 − a 1 k*r_1-p*r_2=a_2-a_1 k∗r1−p∗r2=a2−a1
这两个方程就变成了一个形如 a x + b y = c ax+by=c ax+by=c的不定方程,可用扩展欧几里德定理求解。
当 g c d ( r 1 , r 2 ) gcd(r_1,r_2) gcd(r1,r2)不能整除 ( a 2 − a 1 ) (a_2-a_1) (a2−a1)时,方程组无解。
否则,求出 k 0 k_0 k0,满足 k 0 ∗ r 1 − p ∗ r 2 = a 2 − a 1 k_0*r_1-p*r_2=a_2-a_1 k0∗r1−p∗r2=a2−a1。k的通解为 k = k 0 + b ∗ ( r 2 / g c d ( r 1 , r 2 ) ) k=k_0+b*(r_2/gcd(r_1,r_2)) k=k0+b∗(r2/gcd(r1,r2))。
代入方程组 x = k ∗ r 1 + a 1 x=k*r_1+a_1 x=k∗r1+a1中,则 x = ( k 0 + b ∗ ( r 2 / g c d ( r 1 , r 2 ) ) ) ∗ r 1 + a 1 = k 0 ∗ r 1 + b ∗ l c m ( r 1 , r 2 ) + a 1 x=(k_0+b*(r_2/gcd(r_1,r_2)))*r_1+a_1=k_0*r_1+b*lcm(r_1,r_2)+a_1 x=(k0+b∗(r2/gcd(r1,r2)))∗r1+a1=k0∗r1+b∗lcm(r1,r2)+a1,其中b为任意整数。
即 x ≡ ( k 0 ∗ r 1 ) + a 1 ( m o d l c m ( r 1 , r 2 ) ) x\equiv(k_0*r_1)+a_1\pmod{lcm(r_1,r_2)} x≡(k0∗r1)+a1(modlcm(r1,r2))
这个方程合并了原来两个方程,但 x x x的解与原方程相同。
使用这个方法,不断合并方程组中的两个方程,直到只剩一个方程,就得到 x x x的通解了。
参考博客:https://blog.csdn.net/DeepStarSky/article/details/107699504