EXCRT中国剩余定理(luogu搬)

线性同余方程:

先给一个定理,这个定理告诉我们一元线性方程何时有解,在有解时有多少个膜 m m m 不同于的解。



定理 1:

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 db , 则 $ 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(ab) .这说明存在整数 k k k ,使得 k m = a − b km=a-b km=ab .所以 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=ab .于是, $ 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 dc ,那么方程 $ 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 axmy=b

整数 x x x 是 $ ax\equiv b\pmod{m}$ 的解当且仅当存在 y y y 使得 a x − m y = b ax-my=b axmy=b .

定理 3可知,若 d ∤ b d \nmid b db,则这个丢番图方程无解 . 反之, a x − m y = b ax-my=b axmy=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)t1x0+(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} t1t2(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...,d1

证毕。



上面讨论了一般形式的同余方程,现在由一个特殊一点的形式来定义模的逆

$ 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=mki=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} Mkyk1(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} xak(modmk) .因为 j ≠ k j \neq k j̸=k m k ∣ M j m_k|M_j mkMj ,所以 M j ≡ 0 ( m o d m k ) M_j \equiv0\pmod{m_k} Mj0(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} xakMkykak(modmk) , 这是因为 M k y k ≡ 1 ( m o d m k ) M_ky_k\equiv1\pmod{m_k} Mkyk1(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 k1 个同余方程构成的方程组的一个解 x x x. 记为 m = ∏ i = 1 k − 1 m i m=\prod_{i=1}^{k-1} m_i m=i=1k1mi, 则 x + i ∗ m   ( i ∈ Z ) x+i*m\ (i\in Z) x+im (iZ)是前 k − 1 k-1 k1方程的通解。

考虑第 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+tmak(modmk) .该方程等价于 m ∗ t ≡ a k − x ( m o d m k ) m*t \equiv a_k -x \pmod{m_k} mtakx(modmk),其中 t t t 是未知量。这就是一个线性同余方程,可以用扩展欧几里得算法判断是否有节,并求出它的解。若有解,则 x ′ = x + t ∗ m x'=x+t*m x=x+tm 就是前 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;
}

好了,关于扩展中国剩余定理就是这样。
(这个代码是有错误的,需要自己寻找)

你可能感兴趣的:(数论,同余)