模线性方程组

模线性方程组(中国余数定理)
题意:给定了n组除数m[i]和余数r[i],通过这n组(m[i],r[i])求解一个x,使得x mod m[i] = r[i]。

直接用中国余数定理,n个m[i]相乘,可能会超出longlong范围

做法:
从n=2开始递推
x mod m[1] = r[1]
x mod m[2] = r[2]
即存在
x = m[1] * k[1] + r[1]
x = m[2] * k[2] + r[2]
推出
m[1] * k[1] - m[2] * k[2] = r[2] - r[1]
可用扩展欧几里德求出k[1]进而求出x,那么
一开始的两个式子即可合并为
X mod lcm(m[1], m[2]) = x  (lcm为最小公倍数)

    for(i=1;i<=n;i++){
        scanf("%lld%lld",&m[i],&r[i]);
    }
    m[0]=m[1];
    r[0]=r[1];
    for(i=2;i<=n;i++){
        ll k1,k2,c;
        c=r[i]-r[0];
        ll gcd=ext_gcd(m[0],m[i],k1,k2);
        if(c%gcd){
            ans=-1;
            break;
        }
        m[i]/=gcd;
        c/=gcd;
        k1=(k1*c)%m[i];
        if(k1<0)
            k1+=m[i];
        r[0]=m[0]*k1+r[0];     // x
        m[0]=m[0]*m[i];        // 最小公倍数
        ans=r[0];
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值