不等式

题目描述
小z热衷于数学。
今天数学课的内容是解不等式:L<=S*x<=R 。小z心想这也太简单了,不禁陷入了深深的思考:假如已知L,R,S,M ,满足L<=(S*x) mod M<=R 的最小正整数x该怎么求呢?
输入
包含多组数据。
第一行包含一个整数T,表示数据组数,接下来是T行,每行为四个正整数M,S,L,R 。

输出
对于每组数据,输出满足要求的x值,若不存在,输出-1 。

样例输入
1
5 4 2 3
样例输出
2
提示
30%的数据中保证有解并且答案小于等于10^6;
另外20%的数据中保证L=R;
100%的数据中T<=100,M,S,L,R<=10^9。

直接枚举答案便可以得到的分数。
的部分分用扩展欧几里得可以解决,这里不做过多阐述。
对于的做法,首先我们排除特殊情况,不妨设,0<=l<=r,0<=s<=m。
显然若存在一个的倍数满足l<=s*x<=r,那么此时的答案就是x。
若不存在,我们不妨将约束式改写成代数式l<=s*x-m*y<=r。进一步改写成以为y主元,即-r<=m*y-s*x<=-l,再把它还原为取模的形式:(-r mod s)<=m*y mod s<=(-l mod s)。若能求出最小的满足上式的y值,则可以求出唯一满足上式的x值(因为区间中没有s的倍数)。
所以我们只需要将读入的四个数标准化,判断是否存在简单解以及判断无解,假如需要的话递归调用函数,直至问题解决。
具体实现可以参考标程。

var
t,m,s,l,r:int64;
function dfs(m,s,l,r:int64):int64;
var
x,k,i: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;
  i:=(l-1)div s +1;
  if i*s<=r then exit(i);
  k:=dfs(s,m,(-r mod s+s) mod s,(-l mod s+s) mod s);
  if k=-1 then exit(k);
  x:=(r+m*k) div s;
  if (s*x-m*k)>=l then exit((x mod m+m) mod m) else exit(-1);
end;

begin
  readln(t);
  while t>0 do
  begin
    t:=t-1;
    readln(m,s,l,r);
    if r>=m then r:=m-1;
    writeln(dfs(m,s,l,r));
  end;
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值