青蛙的约会
设跳k次,能遇到一起,说明到了同一个点,(x + k * m) = (y + k * n) (mod l), k *(n - m) = (x - y) (mod l)
k * (n - m) + t * l = x - y; 令a = n - m; x = k; y = t; b = l; c = x - y;
ax + by = c 注意a,b 必须是非负整数
ax + by = gcd(a,b) = d;得到特解x0
如果ax + by = c 有解,说明 d | c; x = x0 * c / d;
x最小的非负整数 x = (x0 * c / d % b / d + b / d) % b / d
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; #define int long long int x,y,n,m,l,x0,yy,d; int exgcd(int a,int b,int &x,int &y){ if(!b){ x = 1,y = 0; return a; } d = exgcd(b,a % b,y,x); y -= x * (a / b); return d; } signed main(){ //freopen("in","r",stdin); ios::sync_with_stdio(0); cin >> x >> y >> m >> n >> l; int a = n - m, b = l, c = x - y; if(a < 0) a = -a, c = -c; exgcd(a,b,x0,yy); if(c % d != 0) cout << "Impossible"; else cout << (x0 * (c / d) % (b / d) + b / d) % (b / d); return 0; }
注:这里面返回d是最大公约数,x0是一个特殊解