[模板][洛谷P1516]青蛙的约会(exgcd)

题目←

设k步后相遇
题目实际要求

X+mkY+nk(modL)

不写成同余方程的话,就是
X+mkqL=Y+nkpL

移项
(mn)k+L(pq)=YX

m - n –>a,L –>b,Y - X –>c,k –> x,p - q –>y
那么就是熟悉的ax + by = c了
众所周知exgcd解得是ax + by = gcd(a,b)这个方程
所以将c写成gcd(a,b)*t//若不能整除gcd(a,b),无解
可以先解出ax+by = gcd(a,b)的解和通解,再乘上t即为原方程解

关于通解
在ax+by = gcd(a,b)中,已知一组解x,y
x0 = x + (b/gcd(a,b))*t,y0 = y - (a/gcd(a,b))*t
正负号可颠倒

关于最小正整数解
设m = b/gcd(a,b),
最小正整数解 X = (x%m + m)%m
//处理取模时出现的负数可用

//负数也可以正常扩欧 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
LL X,Y,N,M,L,x,y,a,b,m,G;
LL Gcd(LL a,LL b){
    return b ? Gcd(b,a%b) : a;
}
void exgcd(LL a,LL b){
    if(!b){
        x = 1;
        y = 0;
        return;
    }
    exgcd(b,a%b);
    LL tmp = y;
    y = x - (a/b)*y;
    x = tmp;
}
int main(){
    cin >> X >> Y >> M >> N >> L;
    G = Gcd(M - N,L);
    if((Y - X)%G){
        printf("Impossible");
        return 0;
    }
    LL t = (Y - X)/G;//
    m = L/G;//X0 = X +- (b/gcd); 
    a = (M - N)/G;b = L/G;//!!!(M - N)/t,L/t->t
    exgcd(a,b);
    x *= t;//一组解 
    m = abs(m);//若m为负,相当于 -= m 
    x = (x%m + m)%m;
    cout << x;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值