用扩展欧几里得算法求解线性同余方程就可以了,要注意求出来的应该是最小非负数。
等价于求方程k(m-n)与(y-x)关于l同余,k为非负整数的解
方程:
k*(m-n)-ld=y-x
若y-x不是gcd(m-n,l)的倍数输出impossible,否则用ext_gcd求出一个解,然后不断使得k+=l/gcd(m-n,l)直到>0或者k-=l/gcd(m-n,l)直到<0即可。
#include <vector> #include <list> #include <limits.h> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <string.h> #include <stdlib.h> using namespace std; long long L; long long extended_euclidean(long long a, long long b, long long &x, long long &y){ if(b==0){ x = 1; y = 0; return a; } long long g = extended_euclidean(b, a%b, x, y); long long tmp = x; x = y; y = tmp - (a/b)*y; return g; } int main(){ long long x, y, m, n; cin>>x>>y>>m>>n>>L; long long a = (m-n+L)%L; long long b = L; long long c = (y-x+L)%L; long long g = extended_euclidean(a, b, x, y); if(c%g != 0){ cout<<"Impossible"<<endl; return 0; } long long k = c/g; x = (x*k); if(x < 0) x = (L/g-(abs(x)%(L/g))); if((x-L/g) > 0) x = x%(L/g); cout<<x<<endl; //system("pause"); return 0; }