Description
小z热衷于数学。
今天数学课的内容是解不等式:L<=S*x<=R。小z心想这也太简单了,不禁陷入了深深的思考:假如已知L、R、S、M,满足L<=(S*x)mod M<=R的最小正整数x该怎么求呢?
Input
第一行包含一个整数T,表示数据组数,接下来是T行,每行为四个正整数M、S、L、R。
Output
对于每组数据,输出满足要求的x值,若不存在,输出-1。
Sample Input
1
5 4 2 3
Sample Output
2
Data Constraint
30%的数据中保证有解并且答案小于等于10^6;
另外20%的数据中保证L=R;
100%的数据中T<=100,M、S、L、R<=10^9。
分析:
类似于辗转相除法。
l<=sx mod m<=r
–> l<=sx-my<=r
–> -r<=my mod s<=-l
若求出的x满足条件就输出x,
否则求出y,再计算x,
要算出y,就要继续dg下去。
特判:若l=0 or s=0 or l>r or l>=m那么无解。
若一开始r>m,那么r=m-1。
代码:
var
t,m,s,l,r:int64;
i:longint;
function exgcd(m,s,l,r:int64):int64;
var
x,y,z:int64;
begin
if l=0 then exit(0);
if l>=m then exit(-1);
if l>r then exit(-1);
if s mod m=0 then exit(-1);
s:=s mod m;
z:=(l-1) div s+1;
if z*s<=r then exit(z);
x:=exgcd(s,m,(-r mod s+s) mod s,(-l mod s+s) mod s);
if x=-1 then exit(-1);
y:=(r+m*x) div s;
if s*y-m*x>=l then exit((y mod m+m) mod m)
else exit(-1);
end;
begin
assign(input,'solve.in');
assign(output,'solve.out');
reset(input);
rewrite(output);
readln(t);
for i:=1 to t do
begin
readln(m,s,l,r);
if r>=m then r:=m-1;
writeln(exgcd(m,s,l,r));
end;
close(input);
close(output);
end.