用拓展欧几里得来做。
x+km=y+kn(mod l)化简成为 (m-n)k=y-x(mod l) 参照方程ax+by=c
然后就是求最大公约数和方程组求解了。
连着4次编译错误——错误时——b=long long(abs(b))——
error: expected primary-expression before 'long'
后来改成b=(long long)abs(double(b))就成功了。
该解题过程可以作为解线性同余方程的模板。这道题因为输入输出只有一个,所以即使是用了cin cout用时也是相当的短,0ms飘过。
做的时候出了一点差错,后来的是a/=d,b/=d,c/=d,但是原来写成了a/=gcd(a,b),b/=gcd(a,b),c/=gcd(a,b).因为a,b已经改过,所以导致后面的数字出了问题。
所以经验是——绝对不要为了写少一点变量而导致变量重复利用出错,即使是全局与局部也是不好的。
最后,因为这道题我使用的是long long 变量,所以我觉得很有必要说一下我在64位的输入输出时吃的亏:
有一次做一道超水的题,比赛时怎么看都看不出错误,但却一直WA,郁闷死我了。
比赛结束后问一个同学我的代码有什么问题,他看老半天也没发现错误在什么地方。最后他把我的scanf,printf的输入输出改为cin cout 就过了。
所以说,做题时要小心64位的输入输出,不同OJ使用的编译器可能不一样,很容易吃亏。
好啦,教训就总结到这里。
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
void exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return ;
}
exgcd(b,a%b,x,y);
long long t=x;
x=y;
y=t-a/b*y;
return ;
}
int main()
{
long long x,y,m,n,l;
cin>>x>>y>>m>>n>>l;
{
long long a,b,c;
a=m-n;
c=y-x;
b=l;
if(c%gcd(a,b))
{
cout<<"Impossible"<<endl;
return 0;
}
else
{
long long xx,yy;
long long d=gcd(a,b);
a/=d;
b/=d;
c/=d;
exgcd(a,b,xx,yy);
xx*=c;
b=(long long)abs(double(b));
xx=(xx%b+b)%b;
cout<<xx<<endl;
}
}
}