求解同余方程组:
{
x
≡
r
1
(
m
o
d
m
1
)
x
≡
r
2
(
m
o
d
m
2
)
⋯
x
≡
r
n
(
m
o
d
m
n
)
\left\{\begin{matrix} x\equiv r_1 \pmod {m_1}\\ x\equiv r_2 \pmod {m_2}\\ \cdots\\ x\equiv r_n \pmod {m_n}\\ \end{matrix}\right.
⎩⎪⎪⎨⎪⎪⎧x≡r1(modm1)x≡r2(modm2)⋯x≡rn(modmn)
①中国剩余定理
当 m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,⋯,mn互质时,可用中国剩余定理解 x x x。
设 M M M为 m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,⋯,mn的最小公倍数(LCM),由于各项互质,则有
M = ∏ i = 1 n m i M=\displaystyle\prod^n_{i=1}m_i M=i=1∏nmi
对于每一个同余方程,设一个 t i t_i ti,为同余方程 M m i t i ≡ 1 ( m o d m i ) \frac{M}{m_i}t_i\equiv 1\pmod {m_i} miMti≡1(modmi)的最小非负整数解。
则可解得同余方程组:
- 特解: x = ∑ i = 1 n r i M m i t i x=\displaystyle\sum^n_{i=1}r_i\frac{M}{m_i}t_i x=i=1∑nrimiMti
- 通解: X = x + k M          ( k ∈ Z ) X=x+kM\;\;\;\;(k\in Z) X=x+kM(k∈Z)
- 最小非负整数解: x m i n = ( x m o d    M + M ) m o d    M x_{min}=(x\mod M+M)\mod M xmin=(xmodM+M)modM
模板:
void exgcd(LL a,LL b,LL &d,LL &x,LL &y) //拓展欧几里得 解单个同余方程
{
if(b==0)
{
x=1;
y=0;
d=a;
}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
LL r[maxn],m[maxn];
LL CRT()
{
LL M=1,res=0;
for(int i=1;i<=n;i++)
M*=m[i]; //最小公倍数LCM
LL a,b,d,x,y;
for(int i=1;i<=n;i++)
{
a=M/m[i],b=m[i];
exgcd(a,b,d,x,y); //解同余方程:M/m[i] * t ≡ 1 (mod m[i])
//由于M/m[i]和m[i]互质,gcd恰为 1,所以一定有解
x=(x%b+b)%b; //最小非负整数解
res=(res+r[i]*(M/m[i])*x)%M; //加到特解当中
}
return res;
}
②拓展中国剩余定理
当 m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,⋯,mn不一定互质时,需用拓展中国剩余定理解 x x x。
设 M k M_k Mk 为 m 1 , m 2 , ⋯   , m k m_1,m_2,\cdots,m_k m1,m2,⋯,mk(即前 k k k个 m m m)的 最小公倍数(LCM),前 k k k个方程组的一个特解为 x k x_k xk。
对于 第 k k k个同余方程,设一个 t t t,为同余方程 x k − 1 + t ∗ M k − 1 ≡ r k ( m o d m k ) x_{k-1}+t*M_{k-1}\equiv r_k\pmod {m_k} xk−1+t∗Mk−1≡rk(modmk) 的最小非负整数解。
则有 x k = x k − 1 + t ∗ M k − 1 x_k=x_{k-1}+t*M_{k-1} xk=xk−1+t∗Mk−1。
递推可解得同余方程组:
- 特解: x n x_n xn
- 通解: X = x n + k M n          ( k ∈ Z ) X=x_n+kM_n\;\;\;\;(k\in Z) X=xn+kMn(k∈Z)
- 最小非负整数解: x m i n = ( x n m o d    M n + M n ) m o d    M n x_{min}=(x_n\mod M_n+M_n)\mod M_n xmin=(xnmodMn+Mn)modMn
模板:
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(b==0)
{
x=1;
y=0;
d=a;
}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
LL r[maxn],m[maxn];
LL EXCRT()
{
LL M=m[1],res=r[1];
LL a,b,c,d,x,y,t;
for(int i=2;i<=n;i++)
{ //c转为正
a=M,b=m[i],c=((r[i]-res)%m[i]+m[i])%m[i];
exgcd(a,b,d,x,y); //求解同余方程:t*M ≡ r[i]-x (mod m[i])
if(c%d!=0)
return -1; //无解
t=b/d;
x=x*c/d;
x=(x%t+t)%t;
res+=x*M; //更新x
M*=t; //更新LCM:M = M*m[i]/gcd(M,m[i])
res=(res%M+M)%M;
}
return res;
}