扩展欧几里得解同余方程组

本文介绍了一种解决不互质模数下同余方程组的方法,通过转换方程形式并使用扩展欧几里得算法求解,最终合并为一个不定方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

就是让你求解同余方程

前言

如果所有的模数互质,那么是可以用中国剩余定理求解的,并且代码特别的段
但是如果不互质的话,如果你要用中国剩余定理来解的话就显得没这么方便了,因为你在求那个类似逆元的东西不好求,并且暴力求的话时间也不允许
所以就需要一个更优秀的东西来解

解法

我们观察两个同余方程
xa1(modm1)x≡a1(modm1)
xa2(modm2)x≡a2(modm2)
其实这个可以写成以下形式
xy1m1=a1x−y1∗m1=a1
xy2m2=a2x−y2∗m2=a2
两个式子相减可以得到
y1m1y2m2=a2a1y1∗m1−y2∗m2=a2−a1
然后这里m1,m2,(a2a1)m1,m2,(a2−a1)都是已知的
所以我们可以当一个不定方程来解
这样的话就是我们可以解出一个y1y1
待回去就可以得到一个可能的x0x0
但是这个x0x0并不是合法的
他仅仅满足下面这个式子x=x0+klcm(m1,m2)x=x0+k∗lcm(m1,m2)
这个的话又可以看成一个新的同余方程
xx0(mod[m1,m2])x≡x0(mod[m1,m2])
然后如果满足这个方程就可以满足那两个方程了
然后就成功地吧两个方程合为一个
然后一直合下去
就可以得到一个唯一的不定方程
这个的话直接用扩展欧几里得来解就可以了

CODE:

#include<cstdio>
typedef long long LL;
LL exgcd (LL a,LL b,LL &x,LL &y)
{
    if (a==0)
    {
        x=0;y=1;
        return b;
    }
    LL tx,ty;
    LL d=exgcd(b%a,a,tx,ty);
    x=ty-(b/a)*tx;
    y=tx;
    return d;
}
int main()
{
    LL n;
    LL b1,m1;
    bool tf=true;
    scanf("%lld",&n);
    scanf("%lld%lld",&b1,&m1);
    for (LL u=2;u<=n;u++)
    {
        LL b2,m2;
        scanf("%lld%lld",&b2,&m2);
        LL A,B,x,y,dd=b2-b1;
        A=m1,B=m2;
        LL d=exgcd(A,B,x,y);
        if (dd%d!=0) {printf("no solution!");return 0;}
        x=(x*(dd/d)%(B/d)+(B/d))%(B/d);
        b1=m1*x+b1;
        m1=m1*m2/d;
    }
    if (tf==false) printf("no solution!");
    else printf("%lld\n",b1);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值