CRTとExCrt

\(CRT \)

無期限解決方程式

IMG

\(M = \ PROD \ limits_i ^ nm_i \)

\(M_I = \ FRAC {M} {M_I} = PRODの\のlimits_ \ {K、K \ NEQ I} ^ nm_k \)

\(T_I \)\(M_I \)金型内の\(M_I \)逆元

結論最初の一般解(\ \和\ limits_i ^ na_iM_it_i MOD LCM(M_I)\)

証明:

方程式の最初のセットのために\(私は\)と考えられ、式

\(\ M_k(k個の\ NEQ I)MOD M_I = 0 \ため)

\(\従って\和\ limits_ {K、K \ NEQ I} ^ na_kM_kt_kの\ equiv0(MOD M_I)\)

\(\ \ t_iM_iの\ equiv1(MOD M_I)ので)

\(\のでa_iM_it_i \当量a_iを(MOD M_I)\)

$ \したがって、\合計\ limits_i ^ na_iM_it_i \当量のa_iを(MOD M_I)$

リーガルソリューション

証明され、一般解\(\合計\ limits_i ^ na_iM_it_iモッズLCM(M_I)\)


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 tp=x;
    x=y; y=tp-a/b*y;
}

int china()
{
    int ans=0,lcm=1,x,y;
    for(int i=1;i<=k;++i) lcm*=b[i];
    for(int i=1;i<=k;++i)
    {
        int tp=lcm/b[i];
        exgcd(tp,b[i],x,y);//求逆元
        x=(x%b[i]+b[i])%b[i];//x要为最小非负整数解
        ans=(ans+tp*x*a[i])%lcm;
    }
    return (ans+lcm)%lcm;
}

ExCrt

解決するために、中国の剰余定理を拡張である(M_I \)\しない互いに素問題

マクロは、その一般解の式を直接表現することはできません、直接一般的なソリューションを構築しなくなりました

誘導によって、考慮前(K-1 \)\方程式の一般解\(X(MOD M)、 M = LCM(M_1 {K-1} M_するために)\ )

私たちは、セクションに準拠する必要があります\(k個\)式は、いくつかの数字を追加する必要がありますが、フロントのことを確実にするために、\(K-1 \)我々は唯一の回数を追加することができ、式がまだホールド(M \)\、それが発見されます\(X + T *のM \の当量のa_k(MOD m_k)\)

照合与えるには、\(T * Mは\当量をa_k -x(MOD m_k)\)

ユークリッドは、合同式が解を持たないならば、全体の方程式が解を持たない、拡張することによって解決することができます

そうでない場合は、新しいソリューションです\(X +のT *のM( MOD LCM(M、m_kは))\)

コードを説明するためのいくつかの詳細があります。

lt exgcd(lt a,lt b,lt &x,lt &y)
{
    if(b==0){x=1;y=0;return a;}
    lt gcd=exgcd(b,a%b,x,y);
    lt tp=x;
    x=y; y=tp-a/b*y;
    return gcd;
}

lt excrt()
{
    lt x,y,k;
    lt M=bi[1],ans=ai[1];//一开始赋为初始值
    for(int i=2;i<=n;i++)
    {
        lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//注意取模保证是正数
        lt gcd=exgcd(a,b,x,y),bg=b/gcd;//t*M-y*mk=gcd,gcd为M和mk的gcd
        if(c%gcd!=0) return -1; //因为求解是根据gcd而不是c,所以还要乘倍数,如果不是倍数证明无解
        
        x=mul(x,c/gcd,bg);//将x乘倍数,这里取模mk/gcd的原因是x(也就是t)还要乘M,乘M之后不能超过LCM(M,mk),也就是不能超过M*m/gcd,所以这里直接对m/gcd取模即可
        ans+=x*M;//答案更新
        M*=bg;//模数更新
        ans=(ans%M+M)%M;//处处取模小心负数
    }
    return (ans%M+M)%M;
}

おすすめ

転載: www.cnblogs.com/Liuz8848/p/11372787.html