洛谷 P1516 青蛙的约会

题意:模L意义下,数轴上两个点x和y,以m和n的步长同方向开始跳,问多久相遇

设t秒后相遇,有

[x+mtequiv y+ntquad (modquad L)\ ]

写成等式的形式

[x+mt=y+nt+kL ]

移项可得

[(n-m)t+kL=x-y ]

这是形如Ax+By=C的不定方程,可以用exgcd求解

注意我们要求最小的非负整数t,因而需要将求出的特解t进行移动

由结论,t移动的步长为k/g,其中g为(n-m,k)

因而需要t%=stp,然后有负数要取正

#include <bits/stdc++.h>
#define int long long
using namespace std;

int exgcd(int a, int b, int &x, int &y) {
	if (!b)
		return x = 1, y = 0, a;
	int ret = exgcd(b, a % b, x, y);
	int t = x;
	x = y;
	y = t - a / b * y;
	return ret;
}

int x, y, m, n, L;

signed main() {
	cin >> x >> y >> m >> n >> L;
	int g = __gcd(n - m, L);
	if ((x - y) % g)
		return puts("Impossible"), 0;
	int t, k;
	exgcd(n - m, L, t, k);
	t *= (x - y) / g;
	int stp = L / g;
	if (stp < 0)
		stp = -stp;
	t %= stp;
	while (t > stp)
		t -= stp;
	while (t < 0)
		t += stp;
	cout << t;
	return 0;
}