[模板][洛谷P1516]青蛙的约会(exgcd)
设k步后相遇
题目实际要求$$X + mk\equiv Y + nk(mod L)$$
不写成同余方程的话,就是$$X + mk - qL = Y + nk - pL$$
移项$$(m - n)k + L(p - q) = Y - X$$
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;
}

浙公网安备 33010602011771号