先给一个定理,这个定理告诉我们一元线性方程何时有解,在有解时有多少个膜 m m m 不同于的解。
设 a , b a,b a,b 和 m m m 是整数,$m>0\ $, g c d ( a , m ) = d \ gcd(a,m)=d gcd(a,m)=d .若 d ∤ b d \nmid b d∤b , 则 $ ax\equiv b\pmod{m}$ 无解。反之, 则 $ ax \equiv b \pmod{m}$ 恰有 d d d 个膜 m m m 不同余的解。
要证明这个定理我们再给一个定理 2:(放心,绝对不会无限递归)
若 a , b a,b a,b 和 m m m 是整数, $ ax\equiv b\pmod{m}$ 当且仅当存在整数 k k k,使得 a = b + k m a=b+km a=b+km
证明一下这个定理 2:
若 $ ax\equiv b\pmod{m}$ ,则 m ∣ ( a − b ) m|(a-b) m∣(a−b) .这说明存在整数 k k k ,使得 k m = a − b km=a-b km=a−b .所以 a = b + k m a=b+km a=b+km .
反过来,若存在整数 k k k 使得 a = b + k m a=b+km a=b+km ,则 k m = a − b km=a-b km=a−b .于是, $ m|(a-b)$ , 因而 $ ax\equiv b\pmod{m}$.
上面这个定理 2还是简单的,可以帮助我们将同余式转换为等式.
还有一个定理
定理 3:
设 a , b a,b a,b 是整数且 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b). 如果 d ∤ c d \nmid c d∤c ,那么方程 $ ax+by=c$ 没有整数解。反之,则存在无穷多个整数解。另外,如果 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0 是方程的一组特解,那么所有的解可以表示为:
x = x 0 + ( b / d ) n , y = y 0 − ( a / d ) n x=x_0+(b/d)n \ \ ,\ \ y=y_0-(a/d)n x=x0+(b/d)n , y=y0−(a/d)n
红红火火恍恍惚惚,这个大家自己脑子里随便想想都能证明。
定理1的正规证明还是很长的,这里我们简单说说。
由定理 2我们可以将 $ ax\equiv b\pmod{m}$ 转换为 二元线性的方程(这是线性丢番图方程):
a x − m y = b ax-my=b ax−my=b
整数 x x x 是 $ ax\equiv b\pmod{m}$ 的解当且仅当存在 y y y 使得 a x − m y = b ax-my=b ax−my=b .
由定理 3可知,若 d ∤ b d \nmid b d∤b,则这个丢番图方程无解 . 反之, a x − m y = b ax-my=b ax−my=b 有无穷多解 :
x = x 0 + ( m / d ) t , y = y 0 + ( a / d ) t x=x_0+(m/d)t \ \ ,\ \ y=y_0+(a/d)t x=x0+(m/d)t , y=y0+(a/d)t
但是我们要找的是不同余的解,所以我们要找一个条件,使得 x 1 , x 2 x_1,x_2 x1,x2 膜 m m m 同余。
找到同余的条件是这样的:
x 0 + ( m / d ) t 1 ≡ x 0 + ( m / d ) t 2 ( m o d m ) x_0+(m/d)t_1 \equiv x_0+(m/d)t_2 \pmod{m} x0+(m/d)t1≡x0+(m/d)t2(modm)
化简:
( m / d ) t 1 ≡ ( m / d ) t 2 ( m o d m ) (m/d)t_1 \equiv (m/d)t_2 \pmod{m} (m/d)t1≡(m/d)t2(modm)
因为 g c d ( m / d ) ∣ m gcd(m/d)|m gcd(m/d)∣m ,所以 $gcd(m,m/d)=m/d\ $ , 可得:
t 1 ≡ t 2 ( m o d m ) t_1 \equiv t_2 \pmod{m} t1≡t2(modm)
这表明不同余的解的一个完全集合可以通过取 $ x=x_0+(m/d)t_1$ 得到,然后 t t t 取遍膜 d d d 的完全剩余系,这样,一个确定的集合就可以给出啦~~其中 t = 0 , 1 , 2 , 3 , 4... , d − 1 t=0,1,2,3,4..., d-1 t=0,1,2,3,4...,d−1。
证毕。
上面讨论了一般形式的同余方程,现在由一个特殊一点的形式来定义模的逆。
$ ax\equiv 1\pmod{m}$ ,由上面的定理可知,此方程有解且仅当 g c d ( a , m ) = 1 gcd(a,m)=1 gcd(a,m)=1 .(也就是 a , m a,m a,m 互质?)。于是其所有的解都膜 m m m同余。
规定(龟腚(啥呀–乌龟的屁股)):
给定整数 a a a ,且满足 g c d ( a , m ) = 1 gcd(a,m)=1 gcd(a,m)=1 ,称 $ ax\equiv 1\pmod{m}$ 的一个接为 a a a 膜 m m m 的逆。
铺垫完以后,就进入正题。
中国剩余定理带上扩展两字后,就从特殊一点的形式转化为了更一般的形式。
先看 m m m 互质的,看了之前的,也知道这是一个限制条件。
首先,构造同余方程组的一个联立解。为此,令 M k = ∏ i = 1 r m i m k M_k= \dfrac{\prod_{i=1}^r m_i }{m_k} Mk=mk∏i=1rmi。因为 j ≠ k j \neq k j̸=k 时 g c d ( m j , m k ) = 1 gcd(m_j,m_k)=1 gcd(mj,mk)=1,知 g c d ( M k , m k ) = 1 gcd(M_k,m_k)=1 gcd(Mk,mk)=1.可求得 M k M_k Mk 膜 m k m_k mk 的一个逆 $ y_k$,所以 M k ∗ y k ≡ 1 ( m o d m k ) M_k *y_k \equiv 1\pmod{m_k} Mk∗yk≡1(modmk).现在构造和:
x = a 1 M 1 y 1 + a 2 M 2 y 2 . . . + a r M r y r x=a_1M_1y_1+a_2M_2y_2...+a_rM_ry_r x=a1M1y1+a2M2y2...+arMryr (如果是要解方程,这里就结束了,但是接下来我们给出证明)
整数 x x x 就是 r r r 个同余方程的联立解。要证明这一点,只需要证明对于 k = 1 , 2 , . . . , r k=1,2,...,r k=1,2,...,r 有 x ≡ a k ( m o d m k ) x\equiv a_k \pmod{m_k} x≡ak(modmk) .因为 j ≠ k j \neq k j̸=k 时 m k ∣ M j m_k|M_j mk∣Mj ,所以 M j ≡ 0 ( m o d m k ) M_j \equiv0\pmod{m_k} Mj≡0(modmk)。因此,在 x x x 的和式中,除了第 k k k 项之外的所有项都和 0 ( m o d m k ) 0 (mod \ m_k) 0(mod mk)同余。从而, x ≡ a k M k y k ≡ a k ( m o d m k ) x \equiv a_kM_ky_k\equiv a_k \pmod{m_k} x≡akMkyk≡ak(modmk) , 这是因为 M k y k ≡ 1 ( m o d m k ) M_ky_k\equiv1\pmod{m_k} Mkyk≡1(modmk).
好啦对于这个特殊的,先上一个代码:
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 zz=x;
x=y;
y=zz-a/b*y;
}
int main()
{
int ans=0,M=1,x,y;
for(int i=1;i<=k;++i)
{
M*=m[i];
}
for(int i=1;i<=k;++i)
{
int zz=M/m[i];
exgcd(zz,m[i],x,y);
x=(x%m[i]+m[i])%m[i];
ans=(ans+zz*x*a[i])%M;
}
cout<<(ans+M)%M;
}
注意,重复强调,这里的 m [ i ] m[i] m[i] 是互质的.
对于模数不满足两两互质,我们也有方法判断线性同余方程组是否有解,并求出方程组的解。请看:
我们可以考虑使用数学归纳法,假设已经求出了前 k − 1 k-1 k−1 个同余方程构成的方程组的一个解 x x x. 记为 m = ∏ i = 1 k − 1 m i m=\prod_{i=1}^{k-1} m_i m=∏i=1k−1mi, 则 x + i ∗ m ( i ∈ Z ) x+i*m\ (i\in Z) x+i∗m (i∈Z)是前 k − 1 k-1 k−1方程的通解。
考虑第 k k k 个方程 求出 t t t 使得 考虑第 k k k 个方程 求出 t t t 使得 x + t ∗ m ≡ a k ( m o d m k ) x+t*m \equiv a_k \pmod{m_k} x+t∗m≡ak(modmk) .该方程等价于 m ∗ t ≡ a k − x ( m o d m k ) m*t \equiv a_k -x \pmod{m_k} m∗t≡ak−x(modmk),其中 t t t 是未知量。这就是一个线性同余方程,可以用扩展欧几里得算法判断是否有节,并求出它的解。若有解,则 x ′ = x + t ∗ m x'=x+t*m x′=x+t∗m 就是前 k k k 个方程构成的方程组的一个解。
综上所述,我们使用 n n n 次扩展欧几里得算法,就求出了整个方程组的解。
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
long long d=exgcd(b,a%b,x,y);
long long kk=x;
x=y;
y=kk-a/b*y;
return d;
}
long long china()
{
long long x,y,k;
long long M=m[1],ans=a[1];
for(int i=2;i<=n;i++)
{
long long a=M,b=m[i]
long long c=(ai[i]-ans%b+b)%b;
long long d=exgcd(a,b,x,y)
long long thea=b/d;
if(c%d!=0)
{
return -1;
}
x=mul(x,c/d,thea);//快速乘龟速乘你们随意,反正我懒得写了。
ans+=x*M;
M*=thea;
ans=(ans%M+M)%M;
}
return (ans%M+M)%M;
}
好了,关于扩展中国剩余定理就是这样。
(这个代码是有错误的,需要自己寻找)