jzoj. 3526. 【NOIP2013模拟11.7A组】不等式(solve)

本文介绍了一种解决特定形式不等式问题的算法,即寻找满足L<=(S*x)modM<=R条件的最小正整数x。通过辗转相除法原理,文章详细解析了算法的设计思路及实现细节,并提供了完整的伪代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值