zoukankan      html  css  js  c++  java
  • Crt and ExCrt

    ### $Crt$

    求解不定方程组

    img

    (M=prodlimits_i^nm_i)

    (M_i=frac{M}{m_i}=prodlimits_{k,k eq i}^nm_k)

    (t_i)(M_i)在模(m_i)时的逆元

    先上结论 通解为(sumlimits_i^na_iM_it_i mod LCM(m_i))

    证明:

    对于方程组中第(i)个方程考虑

    (ecause M_k(k eq i) mod  m_i=0)

    ( herefore sumlimits_{k,k eq i}^na_kM_kt_kequiv0 (mod m_i))

    (ecause t_iM_iequiv1 (mod m_i))

    ( herefore a_iM_it_iequiv a_i (mod m_i))

    $ herefore sumlimits_i^na_iM_it_iequiv a_i (mod m_i) $

    解合法

    得证,通解为(sumlimits_i^na_iM_it_i mod 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到m_{k-1}))

    我们为了符合第(k)个方程,需要加一些数,但为了保证前(k-1)个方程仍然成立,所以只能加若干倍的(M),也就是说找到(x+t*Mequiv a_k(mod m_k))

    上式整理得(t*Mequiv 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;
    }
    
    
  • 相关阅读:
    739. Daily Temperatures
    556. Next Greater Element III
    1078. Occurrences After Bigram
    1053. Previous Permutation With One Swap
    565. Array Nesting
    1052. Grumpy Bookstore Owner
    1051. Height Checker
    数据库入门及SQL基本语法
    ISCSI的概念
    配置一个IP SAN 存储服务器
  • 原文地址:https://www.cnblogs.com/Liuz8848/p/11372787.html
Copyright © 2011-2022 走看看