poj-1061-拓展欧几里德

青蛙的约会,典型拓展欧几里得

首先我们根据题意可得一个公式:X*(m-n)+Y*L=y-x

这样的话解出x,y后判断y-x是不是d的倍数,不是则无解

最终答案是 (X*(y-x)/d)%(L/d),为什么是这个答案呢。首先我们知道上面的表达式最小正整数解是X0*(y-x)/d,然后我们又知道通解就是最小正整数解加k*b/d,实际就是取模b/d,所以就是这个答案。

https://blog.csdn.net/loi_dqs/article/details/49488851   

----------------------------------------------------------------------------------------------------------------------------------

更新~~今天详细看了看最小正整数解的问题。

首先,紫书上告诉的最小正整数解是x0+k*b',实际上就是(x%b+b)%b。

这个题还需要处理m和n的大小,是为了让gcd大于零,这样用上面的方法处理正整数解时不至于因为gcd是负数从而导致解还是负数。

为什么这样处理就行呢,因为余数的正负取决于n,比如n%m=p,p的正负取决于n。

#include <iostream>
#include <cmath>
#include <vector>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long ll;

ll x,y,n,m,l,X,Y;

ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    ll r=ex_gcd(b,a%b,y,x);
    y-=x*(a/b);
    return r;
}

int main()
{
    scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
    if(m<n)//k*L一定是正数了,这里为了保证m-n也是正数
    {
        swap(x,y);
        swap(n,m);
    }
    ll d=ex_gcd(m-n,l,X,Y);
    if((y-x)%d==0) printf("%lld\n",(X*((y-x)/d)%(l/d)+(l/d))%(l/d));//记得处理负数
    else printf("Impossible\n");
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值