【专题】线性同余方程

定义:a,b是整数,形如 axb(mod m) ,且x是未知整数的同余式称为一元线性同余方程。

定理:a,b,m是整数且m>0, gcd(a,m)=d ,如果d|b,则方程恰好有d个模m不同余的解,否则方程无解。

由同余方程的定义式可得 ax+my=b ,这个方程称为二元一次不定方程。

  • 解一元线性同余方程

    设d=gcd(a,m),由定理可知若不满足d|b,那么方程无解;否则:

    a=da0

    m=dm0

    那么方程变为: a0x+m0y=b/d(d)

    由于此时 gcd(a0,m0)=1 ,因此可以运用扩展欧几里得算法得出方程 a0x+m0y=b/d 的解x (a0x(b/d)+m0y(b/d)=1)

    虽然x不唯一,但是属于一个模m剩余系,由定理可知,共有d个模m剩余类满足方程,其代表分别为:(由 a0xbd(mod m0) )

    x,x+m0,x+2m0...x+(d1)m0

  • 例题(POJ 1061青蛙的约会)

    • 题目大意

    在一个圆环上有两只青蛙A和B,从0点自东向西为正方向,两只青蛙的位置分别为x,y,A每次跳m,B每次跳n,环总长为L.两只青蛙同时出发,两只青蛙落在同一点视为相遇,问最少经过几次跳跃两只青蛙相遇。

    • 分析

    设k次相遇,则有 x+mky+nk(mod L)

    转化成 (mn)k(yx)(mod L) 就变成了一个裸的线性同余方程的问题了

    • 代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
typedef long long int LL;
LL Gcd(LL a,LL b)
{
    return b==0?a:Gcd(b,a%b);
}
LL Exgcd(LL a,LL b,LL &x,LL &y)
{
      if(b==0)
      {
            x=1;
            y=0;
            return a;
      }
      else
      {
           LL ans=Exgcd(b,a%b,x,y);
           LL temp=x;
           x=y;
           y=temp-(a/b)*y;
           return ans;
      }
}
//这种写法方便理解
LL f(LL a,LL b,LL m)//求解一元线性同余方程
{
    LL x,y,d;
    LL a0,m0;
    d=Gcd(a,m);
    if(b%d!=0)return -1;
    a0=a/d;
    m0=m/d;
    Exgcd(a0,m0,x,y);
    x=x*b/d;
    x=(x%m0+m0)%m0;
    return x;
}
//这种写法更简洁
LL f2(LL a,LL b,LL m)//求解一元线性同余方程
{
    LL x,y,d;
    d=Exgcd(a,m,x,y);
    if(b%d!=0)return -1;
    x=x*(b/d)%m;
    x=(x%(m/d)+(m/d))%(m/d);
    return x;
}
int main()
{
    LL x,y,m,n,L;
    LL A,B,C,xx,yy,d;
    while(scanf("%I64d %I64d %I64d %I64d %I64d",&x,&y,&m,&n,&L)!=EOF)
    {
        LL ans=f2(n-m,x-y,L);
        if(ans==-1)cout<<"Impossible"<<endl;
        else  cout<<ans<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值