研究同余方程。
先上代码。
#include <iostream>
#include <cstdio>
using namespace std;
long long k, s;
long long exgcd(long long a, long long b){
if(b==0){
k = 1;
s = 0;
return a;
}
long long re=exgcd(b, a%b);
long long t=k;
k = s;
s = t - a / b * s;
return re;
}
int main(){
long long x, y, m, n, l, gcd;
cin>>x>>y>>m>>n>>l;
if(m-n<0){
m ^= n, n ^=m, m ^= n;
x ^= y, y ^=x, x ^= y;
}
if((y-x)%(gcd=exgcd(m-n, l))!=0) printf("Impossible");
else printf("%d", ((y-x)/gcd*k%(l/gcd)+(l/gcd))%(l/gcd));
return 0;
}
要用long long。数据范围好康的!
来推导一下。其实就是
(y+nk)−(x+mk)=sl
,变形易得
(m−n)k+sl=y−x
,即
(m−n)k≡y−x(modl)
。然后用扩展欧几里德即可。
注意,我们总是不希望gcd为负的,所以我们要调换一下当
m−n<0
时。
引用一个做法:
若gcd(a, b) = d,则方程ax ≡ c (mod b)在[0, b/d - 1]上有唯一解。出处
因此应该模l/gcd。