中国剩余定理 CRT
题目描述
给定
n
n
n个同余式,
m
1
,
m
2
.
.
.
,
m
n
m_1,m_2...,m_n
m1,m2...,mn两两互质
问,满足上述同余式最小的
x
x
x是多少
结论
1,设
M
=
m
1
∗
m
2
.
.
.
∗
m
n
M=m_1*m_2...*m_n
M=m1∗m2...∗mn,即
M
=
∏
i
=
1
n
m
i
,
M
i
=
M
/
m
i
M=\prod_{i=1}^nm_i,M_i=M/m_i
M=∏i=1nmi,Mi=M/mi
2,设
t
i
t_i
ti为
M
i
M_i
Mi模
m
i
m_i
mi的逆元,即
t
i
∗
M
i
≡
1
(
m
o
d
m
i
)
t_i*M_i\equiv1\pmod{m_i}
ti∗Mi≡1(modmi)
3,那么方程组
(
S
)
(S)
(S)的通解形式为
x
=
∑
i
=
1
n
a
i
t
i
M
i
+
k
M
,
k
∈
Z
x=\sum_{i=1}^na_it_iM_i+kM,k\in Z
x=∑i=1naitiMi+kM,k∈Z
证明
易证,在第
i
i
i个同余方程中,对于
∀
j
∈
[
1
,
n
]
\forall j\in [1,n]
∀j∈[1,n],当
i
≠
j
i\ne j
i=j时,有
a
j
M
j
t
j
≡
0
(
m
o
d
m
i
)
a_jM_jt_j\equiv0\pmod{m_i}
ajMjtj≡0(modmi)
而当
i
=
j
i=j
i=j时,有
a
i
M
i
t
i
≡
a
i
(
m
o
d
m
i
)
a_iM_it_i\equiv a_i\pmod{m_i}
aiMiti≡ai(modmi)
因此
∑
i
=
1
n
a
i
M
i
t
i
\sum_{i=1}^na_iM_it_i
∑i=1naiMiti满足题意
例题
P3868-板子
P3868代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int f=1,re=0;char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1,ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';
return re*f;
}
int k,a[100009],b[100009];
int ksm(int a,int b,int mod){
int ans=1;
while(b){
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}return ans;
}
int qmul(int a,int b,int mod){
int ans=0;
while(b){
if(b&1) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}return ans;
}
void exgcd(int a,int b,int &x,int &y){
if(b==0){x=1,y=0;return;}
exgcd(b,a%b,x,y);
int tmp=x;
x=y,y=tmp-a/b*y;
}
int getcrt(){
int lcm=1,ans=0;
for(int i=1;i<=k;i++) lcm*=b[i];
for(int i=1;i<=k;i++){
int x=0,y=0;
exgcd(lcm/b[i],b[i],x,y);
x=(x%b[i]+b[i])%b[i];
ans=(ans+qmul(qmul(lcm/b[i],x,lcm),a[i],lcm))%lcm;
}return (ans+lcm)%lcm;
}
signed main(){
k=read();
for(int i=1;i<=k;i++) a[i]=read();
for(int i=1;i<=k;i++) b[i]=read(),a[i]=(a[i]%b[i]+b[i])%b[i];
printf("%lld\n",getcrt());
return 0;
}