中国剩余定理(孙子定理)

用现代数学的语言来说明的话,中国剩余定理给出了以下的一元线性同余方程组:

有解的判定条件,并用构造法给出了在有解情况下解的具体形式。

中国剩余定理说明:假设整数m1,m2, ... ,mn两两互质,则对任意的整数:a1,a2, ... ,an,方程组

  有解,并且通解可以用如下方式构造得到:

设  是整数m1,m2, ... ,mn的乘积,并设 

是除了mi以外的n- 1个整数的乘积。设 为 模 的数论倒数(  为  模 意义下的逆元) 

方程组  的通解形式为 

在模  的意义下,方程组  只有一个解: 

 

 

其实说了这么多,就是求解下面这一类的一类问题

      有一个数,设为x      已知x%m_1=a_1   x%m_2=a_2  x%m_3=a_3让求解x

 

代码如下:

typedef long long LL;

void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
      if (!b) {d = a, x = 1, y = 0;}
      else{
          ex_gcd(b, a % b, y, x, d);
          y -= x * (a / b);
      }
  }
LL inv(LL t, LL p){//如果不存在,返回-1 
     LL d, x, y;
     ex_gcd(t, p, x, y, d);
     return d == 1 ? (x % p + p) % p : -1;
 }



/************保证两两互质的情况**************************/
LL china(int n, LL *a, LL *m){
    LL M = 1, ret = 0;
    for(int i = 0; i < n; i ++) M *= m[i];
    for(int i = 0; i < n; i ++){
        LL w = M / m[i];
        ret = (ret + w * inv(w, m[i]) * a[i]) % M;
    }
    return (ret + M) % M;   //返回值就为上述x
}





/**************不保证两两互质的情况*********************/
typedef pair PLL;
PLL linear(LL A[], LL B[], LL M[], int n) {//求解A[i]x = B[i] (mod M[i]),总共n个线性方程组 
    LL x = 0, m = 1;
    for(int i = 0; i < n; i ++) {
        LL a = A[i] * m, b = B[i] - A[i]*x, d = gcd(M[i], a);
        if(b % d != 0)  return PLL(0, -1);//答案不存在,返回-1 
        LL t = b/d * inv(a/d, M[i]/d)%(M[i]/d);
        x = x + m*t;
        m *= M[i]/d;
    }
    x = (x % m + m ) % m;
    return PLL(x, m);//返回的x就是答案,m是最后的lcm值 
}

   

你可能感兴趣的:(数论,中国剩余定理,孙子定理)