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

问题

就是让你求解同余方程

前言

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

解法

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

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;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值