Saito Asuka saiko!!!

有些走累了呢 有些走累了呢 虽然以那麼平凡的表现 来形容人生的漫长道路 想稍稍休息下呢 想稍稍休息下呢 时间每分每刻都这样残酷 将我紧拖著前行...

luoguP1516 青蛙的约会|数论|同余|扩展欧几里得算法

青蛙的约会|数论|同余|扩展欧几里得算法

为什么这种乐(S)观(B)的青蛙都能网恋,还成功了(我:???????SB青蛙去死8 青蛙

为什么最近一直在做青蛙的题?(我怕是要无限-1s制了????)

V3

Problem

Problem

分析

先搞懂扩展欧几里得算法8

根据题意可得:

青蛙A:

初始位置x,每次跳m

青蛙B:

初始位置y,每次跳n

总长度为L

求相遇时间(如果有解)t

即换成数学表达式:

\[x+m\cdot t \equiv y+n\cdot t \left(mod \ L\right) \]

根据分析扩展欧几里得算法的步骤:

\[L|\left(x+m\cdot t\right)-\left(y+n\cdot t \right) \]

=>

\[L|\left(x-y\right)+\left(m-n\right)t \]

=>

\[\left(x-y\right)+\left(m-n\right)t=kL,k\in Z^{*} \]

\[n-m=a,x-y=b(a>0,b>0) \]

注意:

如果a<0:

需要把a和b调正:

\[a=-a,b=-b \]

\[a\cdot t+k\cdot L=b \]

方程有解:

当且仅当

\[gcd\left(a,k\right)|b \]

如果有解:

\[a\cdot t+L\cdot k=gcd\left(a,k\right) \]

根据扩展欧拉定理得一个解t0

之后对t0进行操作得到t的一个解:

\[t=t_0\cdot \frac{b}{gcd\left(a,k\right)} \]

再进行调正:

\[t=\left(t\%\frac{L}{d}+\frac{L}{d}\right)\%\frac{L}{d} \]

Code

#include <cstdio>
#include <iostream>
#define ll long long 
using namespace std;
ll x,y,m,n,l,t,k;
ll exgcd(ll a,ll b,ll &x,ll &y){
	if(b==0){
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,x,y);
	int tmp=x;x=y;y=tmp-(a/b)*y;
	return d;
}
int main(){
	scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
	ll a=n-m,b=x-y;
	if(a<0) a=-a,b=-b;//修正为正数 
	ll d=exgcd(a,l,t,k);
	if(b%d==0){
		t=t*b/d;//获得一个解
		t=(t%(l/d)+(l/d))%(l/d);//修正负数 
		printf("%lld",t);
	}else printf("Impossible");
	return 0;
}
posted @ 2019-01-30 16:42  斋藤飞鸟  阅读(180)  评论(2编辑  收藏  举报
动画加载完毕