poj1061 扩展欧几里得

本文介绍了如何利用扩展欧几里得算法解决形如(ax + by = c)的线性同余方程,并通过实例演示了如何找到满足条件的最小非负整数解t。

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

欧几里得:求a,b最大公约数的辗转相除法

扩展欧几里得:一定存在x,y使得 a*x+b*y = gcd(a,b)成立

证明见  http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 这个博客


题意:(n-m) *t + L *p = x-y    设 a= n-m      ,b=L     ,x-y=c      ,gcd(a,b) =d 求使之成立的非负最小  t或者直接说不成立输出impossible

变成a*t + b *p = c


扩展欧几里得:a*t0 + b*p0 = d

a整除d,b整除d,所以c必须整除d,不然就。。输出impossible

c整除d时,上式都*(c/d) 得题目要求的式子。。


先求出一个  t0 的解

a*t1 + b*p1 = d

a*t2  + b*p2 =d

t1 - t2 = b (p2-p1)/a

p2 - p1 一定是a/d的倍数

b(p2-p1)/a一定是b/d的倍数    

t0之间每组相差 b/d ,每次加或减就行了

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define ll long long
#define FOR(i,j,k) for(int i =j; i<=k ;i++)
#define ll long long
const int maxn  =50;
ll t,p,d;
ll gcd(ll a,ll b)
{
    return b == 0? a: gcd(b,a%b);
}
void exgcd(ll a,ll b)
{
    if( b == 0)
    {
        t = 1;
        p = 0;
        d = a;//d=gcd(a,b)
    }
    else{
        exgcd(b ,a % b);
        int x = t;
        t = p;
        p = x-a/b *p;
    }
}
int main()
{
    ll n,m,l,x,y;
    while(~scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &l))
    {
        bool  flag = 0;
        ll a = n-m, b= l,c = x-y;
        //if(m == n) flag =1;
        exgcd(a,b);
        if(c % d != 0)
            flag =1;
        if(flag)
            cout<<"Impossible"<<endl;
        else{
            ll v = t*c/d;
            cout<<(v% (b/d) + b/d)%(b/d)<<endl;
        }
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值