• 浅谈中国剩余定理


    数论基础篇吧,与Exgcd有脱不开的关系。

    这个算法,就是要让我们求n个线性同余方程的共同解的最小值,即最小整数解。

    我们可以设:M为所有模数之积,Mi=M/b[i],ti为Mi*ti在模ai(模数)意义下同余1的方程的一组解,且模数均互质。

    我们则有:方程组的特解为M1*t1*b1+...+Mn*tn*bn.

    证明:因为Mi是除了ai之外所有模数的倍数,所以对于任意k≠i,都有bi*Mi*ti≡0(mod ak

    又因为bi*Mi*ti≡bi(mod ai),所以x=∑bi*Mi*ti带入原方程组成立。

    对于T我们直接用Exgcd求解即可。其通解可以表示为x+kM,我们求最小非负整数解时,将x对M取模,并让它落在0~M-1的区间中即可。

    代码实现:

    inline void Exgcd(LL a,LL b,LL &d,LL &x,LL &y){
        if(!b){d=a;x=1;y=0;}
        else{
            Exgcd(b,a%b,d,x,y);
            LL t=x;x=y;y=t-(a/b)*y;
        }
    }
    inline LL IntChina(){
        LL Ans=0,Mi,x,y,d;
        for(LL i=1;i<=n;++i){
            Mi=M/a[i];
            Exgcd(Mi,a[i],d,x,y);
            Ans=((Ans+Mi*x*b[i])%M+M)%M;
        }return (Ans+M)%M;
    }

    例题:曹冲养猪

    中国剩余定理模板题,用上面代码足以AC,代码不在给出。

    例题:猜数字

    这题也算是中国剩余定理的模板题目了,我们列出方程后,只需要进行一下移项,转移成我们熟悉的样子,套用中国剩余定理求解即可。

    注意两点:注意将负数转成非负数。

    注意要用龟速乘。这里大概讲一下龟速乘:

    二进制算法,我们将因数b每次除以2,a每次乘以2,判断b的当前一位是不是1(二进制下),如果是,则说明对最终结果有贡献,便让ans+=a,ans%=mod.注意每次取余。

    这里给出龟速乘的代码,本题代码不再给出。(毕竟笔者这个蒟蒻都自己水了90pts,没用龟速乘。)

    代码:

    #define ll long long
    ll Ksc(ll a,ll b,ll mod){
        ll ans=0;
        for(;b;b>>=1,a=(a+a)%M)if(b&1)ans=(ans+a)%mod;
        return ans;
    } 
  • 相关阅读:
    其他标签
    数组和全局变量
    字符串处理
    运算符
    PHP安装配置工具
    String、StringBuffer与StringBuilder之间区别
    mybits——1
    异常
    ubuntu 系统错误:Error : BrokenCount > 0解决
    ubuntu配置VScode
  • 原文地址:https://www.cnblogs.com/h-lka/p/11222418.html
Copyright © 2020-2023  润新知