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; }