搞搞中国剩余定理和它的扩展

Posted tongseli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搞搞中国剩余定理和它的扩展相关的知识,希望对你有一定的参考价值。

中国剩余定理

解决同余方程组的相关问题,然而貌似扩展一下发生质变?

同余方程组问题

\[x\equiv a_1 \mod m_1 \]

\[x\equiv a_2 \mod m_2 \]

\[\dots\dots\]

\[x\equiv a_n \mod m_n \]

求解满足上述同余方程组的\(x\)

中国剩余定理(CRT)

  • 要求:模数\(m_1,m_2,\dots,m_n\) 必须互质(为什么呢?)
  • CRT告诉我们,这个方程组在模\(M=m_1*m_2*\dots*m_n\) 意义下的解是唯一的。
  • CRT还告诉我们这个解为\[x\equiv a_1 M_1 M_1^-1+a_2 M_2M_2^-1+\dots+a_n M_nM_n^-1 \mod M\]其中\(M_i=M/m_i\) ,而\(M_i^-1\) 是模\(m_i\) 意义下的逆元。
  • \[x=\sum a_i\fracMm_iinv(\fracMm_i,\,m_i)\]
  • 这个解是构造性的解,可以验证其是满足上述方程组的。
  • 为什么两两互质?逆元的要求!
const int maxn=1000;
int a[maxn];
int m[maxn];

int CRT(int n)
    int M=1;
    int ans=0;
    for(int i=1;i<=n;i++)
        M*=m[i];
    
    for(int i=1;i<=n;i++)
        int x,y;
        int Mi=M/m[i];
        exgcd(Mi,m[i],x,y);
        ans=(ans+a[i]*Mi*x)%M;
    
    if(ans<0)ans+=M;
    return ans;

扩展中国剩余定理(exCRT)

  • 模数\(m_1,m_2,\dots,m_n\) 不互质的时候也可以有解啦!
  • 考虑一下同余方程组仅有两个方程的情况。
  • \[x\equiv c_1 \mod m_1 \]\[x\equiv c_2 \mod m_2\]
  • \[x=c_1 +m_1k_1$ ,$x=c_2 +m_2k_2\]
  • \[c_1 +m_1k_1=c_2 +m_2k_2\]
  • \[m_1k_1 =c_2-c_1+m_2k_2\]
  • 这个方程有解的充要条件是\[\gcd(m_1,m_2)\,|\,(c_2-c_1)\]
  • \[\fracm_1k_1\gcd(m_1,m_2) =\fracc_2-c_1\gcd(m_1,m_2)+\fracm_2k_2\gcd(m_1,m_2)\]
  • \[\fracm_1k_1\gcd(m_1,m_2) \equiv\fracc_2-c_1\gcd(m_1,m_2)\mod \fracm_2\gcd(m_1,m_2)\]
  • \[k_1\equiv inv(\fracm_1\gcd(m_1,m_2),\fracm_2\gcd(m_1,m_2))*\fracc_2-c_1\gcd(m_1,m_2)\mod \fracm_2\gcd(m_1,m_2)\]
  • \(inv(a,b)\) 表示\(a\) 在模\(b\) 意义下的逆元
  • \[k_1=inv(\fracm_1\gcd(m_1,m_2),\fracm_2\gcd(m_1,m_2))*\fracc_2-c_1\gcd(m_1,m_2)+K* \fracm_2\gcd(m_1,m_2)\]
  • 带回\(x=c_1 +m_1k_1\)
  • \[x=c_1 +m_1*(inv(\fracm_1\gcd(m_1,m_2),\fracm_2\gcd(m_1,m_2))*\fracc_2-c_1\gcd(m_1,m_2)+K* \fracm_2\gcd(m_1,m_2))\]
  • \[x\equiv c_1 +m_1*inv(\fracm_1\gcd(m_1,m_2),\fracm_2\gcd(m_1,m_2))*\fracc_2-c_1\gcd(m_1,m_2)\mod \fracm_1m_2\gcd(m_1,m_2)\]
  • 到这里,我们已经完成了两个同余方程的整合!有形式\(x\equiv a \mod m\)
  • 其中\[a=c_1 +m_1*inv(\fracm_1\gcd(m_1,m_2),\fracm_2\gcd(m_1,m_2))*\fracc_2-c_1\gcd(m_1,m_2)\] \[m=\fracm_1m_2\gcd(m_1,m_2)\]
  • 反复重复以上操作!(二合一,加一,合一,······)
const int maxn=1000;
int a[maxn];
int m[maxn];

int gcd(int a,int b)
    return b?gcd(b,a%b):a;


int exgcd(int a,int b, int &x,int &y)
    if(b==0)
        x=1;
        y=0;
        return a;
    
    int d=exgcd(b,a%b,x,y);
    int tmp=x;
    x=y;
    y=tmp-a/b*y;
    return d;


int inv(int a,int mod)
    int x,y;
    int d=exgcd(a,mod,x,y);
    return d==1?(x%mod+mod)%mod:-1;


int exCRT(int n)
    int m1, m2, c1, c2, d;
    for(int i=2;i<=n;i++)
        m1=m[i-1];//这里是与前一个进行合并
        m2=m[i];
        c1=a[i-1];
        c2=a[i];
        d=gcd(m1,m2);
        if((c2-c1)%d!=0)
            return -1;//无法合并
        
        m[i]=m[i-1]*m[i]/d;//公式(倒数第二个)
        a[i]=c1+m1*inv(m1/d,m2/d)%(m2/d)*(c2-c1)/d;//公式(倒数第二个)
        a[i]=(a[i]%m[i]+m[i])%m[i];
    
    return a[n];

以上是关于搞搞中国剩余定理和它的扩展的主要内容,如果未能解决你的问题,请参考以下文章

中国剩余定理CRT及 扩展中国剩余定理扩展CRT

中国剩余定理与扩展中国剩余定理

中国剩余定理&&扩展中国剩余定理

中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结

中国剩余定理讲解

中国剩余定理(转载)(中国剩余定理与扩展欧几里德的联系)