[Ybt Gold Medal Navigation 8-6-1] [luogu P1516] Frog Dating/Indefinite Equation Congruence Equation Example

Frog dating

Topic link: ybt gold medal navigation 8-6-1 / luogu P1516

General idea

There are two things jumping in the same direction at their respective positions on the ring, each jumping a certain distance each time.
Then ask how many times you have to jump so that these two things will be in the same place.
If they are not in the same place, they should be output according to the requirements of the title.

Ideas

Then we consider whether we can list the equation.
s + mx = t + nx (mod L) s+mx=t+nx(mod\ L)s+mx=t+nx(mod L)
s , t s,t s,t is the starting position of the two things,m, nm, nm,n is the number of grids that two things jump each time.

Let's make it: (m − n) x = t − s (mod L) (mn)x=ts(mod\ L)(mn)x=ts ( m o d L )  .
This is a linear congruence equation in one variable, and it is natural to think of turning it into a linear indefinite equation in two variables, and then use extended Euclidean to do it.
(m − n) x + L y = t − s (mn)x+Ly=ts(mn)x+Ly=ts

But it must have a solution to have conditions, that is (m − n) (mn)(mn ) andLLL is relatively prime.
If it is not mutually prime, then the output is not feasible, otherwise we will continue to do it.

Then you can make the two on the left coprime: m − n gcd ⁡ (m − n, L) x + L gcd ⁡ (m − n, L) y = t − s gcd ⁡ (m − n, L ) \dfrac{mn}{\gcd(mn,L)}x+\dfrac{L}{\gcd(mn,L)}y=\dfrac{ts}{\gcd(mn,L)}gcd(mn,L)mnx+gcd(mn,L)LY=gcd(mn,L)ts
(Remember to divide the modulus afterwards, because your LL hereL becomesL gcd ⁡ (m − n, L) \dfrac{L}{\gcd(mn,L)}gcd(mn,L)L, It means modulus)

But extended Euclidean is ax + by = 1 ax+by=1ax+by=1 , the right side of the equation is1 11 Ah.
That's simple, we just take the right side of the formula as1 11 , calculatexxx , and then multiply the right side back, and that's it.

Then you get it out and you can output it.

Code

#include<cstdio>
#define ll long long

using namespace std;

ll x, y, m, n, mo;
ll X, Y, a, b, c;

ll GCD(ll x, ll y) {
    
    //普通的求 gcd
	if (!y) return x;
	return GCD(y, x % y);
}

ll exgcd(ll a, ll &x, ll b, ll &y) {
    
    //扩展欧几里得求 ax+by=1
	if (!b) {
    
    
		x = 1;
		y = 0;
		return a;
	}
	
	ll re = exgcd(b, y, a % b, x);
	y -= a / b * x;
	return re;//顺便可以求出 gcd,可用可不用
}

int main() {
    
    
	scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &mo);
	
	//弄出一元线性同余方程,然后转成二元一次不定方程
	a = (m - n + mo) % mo;
	b = mo;
	c = (y - x + mo) % mo;
	
	int gcd = GCD(a, b);//判断是否有解
	if (c % gcd != 0) {
    
    
		printf("Impossible");
		return 0;
	}
	
	a /= gcd;//把式子化成 ax+by=c 且 a,b 互质的形式
	b /= gcd;
	c /= gcd;
	exgcd(a, X, b, Y);
	
	X = (X % mo + mo) % mo;
	printf("%lld", (X * c) % (mo / gcd));//算出答案(记得这里模数不是mo)
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/114157312