Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 92405 | Accepted: 16981 |
Description
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
设跳了t次,A:x+m*t,B:y+n*t,两者要相遇,必满足(x+m*t)-(y+n*t)=k*l;
整理:x-y=l*k+(n-m)*t;有解的情况,gcd(l,n-m)|x-y,否则无解。
接下来就是用扩展欧几里得了,关于这个算法,一定要搞透彻,找本数论书,仔细研究一下。
思路是非常巧妙的,复杂度是log级别(每两次余数减半)。
解得特解p,q.那么首先放大z=(x-y)/gcd(l,n-m)倍,p*=z,q*=z;然后随便加个变量t构造通解:一般x=p-t*(n-m)/gcd(l,n-m),y=q+t*l/gcd(l,n-m);然后解不等式,求个最小的正解。
代码:
#include<cstdio> #include<iostream> #include<cstring> #define ll long long using namespace std; void extend_gcd(ll a,ll b,ll &x,ll &y,ll &q){ if(b==0){x=1;y=0;q=a;} else{ extend_gcd(b,a%b,x,y,q); ll tmp=x;x=y;y=tmp-a/b*y; } } int main() { ll xx,yy,m,n,l,q,ans=1<<30,x,y; while(cin>>xx>>yy>>m>>n>>l){ extend_gcd(l,n-m,x,y,q); if((xx-yy)%q) puts("Impossible"); else{ y*=(xx-yy)/q; ll tmp=y/(l/q); ans=y-tmp*l/q; if(ans<0) ans+=l; cout<<ans<<endl; } } return 0; }