P1516/bzoj1477 青蛙的约会

青蛙的约会

exgcd

根据题意列出方程:

设所用时间为T,相差R圈时相遇

(x+T*m)-(y+T*n)=R*l

移项转换,得

T*(n-m)-R*l=x-y

设a=n-m,b=l,c=x-y,x_=T,y_=R,则

a*x_+b*y_=c

经典的不定方程式,果断用exgcd

当且仅当 gcd(a,b) | c 时,方程有解

我们用exgcd求的方程为 a*x_+b*y_=gcd(a,b)

所以求出的解要 /gcd(a,b)*c

此时我们求出的解不一定是最优解

设x0为最小解

而任意 xi= x0+ b/gcd(a,b)*t

于是我们把这个解 %( b/gcd(a,b) ) 就能得到答案了(注意负数转正)

#include<iostream>
using namespace std;
typedef long long ll;
ll g,x0,y0,X,Y,m,n,l,p;
void exgcd(ll a,ll b,ll &x,ll &y){
    if(!b) x=1,y=0,g=a;
    else exgcd(b,a%b,y,x),y-=x*(a/b);
}
int main(){
    cin>>X>>Y>>m>>n>>l;
    if(n<m) swap(X,Y),swap(m,n); //注意a,b要>0
    exgcd(n-m,l,x0,y0);
    if((X-Y)%g) cout<<"Impossible";
    else p=l/g,cout<<((X-Y)/g*x0%p+p)%p;
}

 

posted @ 2018-10-11 00:20  kafuuchino  阅读(150)  评论(0编辑  收藏  举报