Description
小(z)热衷于数学。
今天数学课的内容是解不等式: (Lle S imes xle R) 。小 (z) 心想这也太简单了,不禁陷入了深深的思考:加入已知 (L,R,S,M) ,满足 (Lle (S imes x) mod M le R) 的最小正整数 (x) 该怎么求呢?
Input
输入文件 (solve.in) 包含多组数据。
第一行包含一个整数 (T) ,表示数据组数,接下来是 (T) 行,每行为四个正整数 (M,S,L,R) 。
Output
输出文件为 (solve.out)
对于每组数据,输出满足要求的 (x) 值,若不存在,输出 (-1) 。
Sample
Sample Input
1
5 4 3 2
Sample Output
2
Limit
$30% $ 的数据中保证有解并且答案小于等于 (10^6)
另外 (20\%) 的数据中保证 (L=R) 。
(100\%) 的数据中 (Tle100,M,S,L,Rle10^9)
Solution
来看原式子 $$Lle (S imes x) mod M le R$$ 改写为 $$Lle S imes x - M imes yle R$$ 设 (y) 为主元 $$-R+S imes x le M imes y le R + S imes x$$ 还原为取模形式 $$-R mod S le (M imes y) mod S le -L mod S$$ 递归求解即可。具体实现见代码。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int read() {
int x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); }
while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag;
}
int solve(int M, int S, int L, int R) {
if(L > R || M < L) return -1;
S %= M;
int ret = (L - 1) / S + 1; if((ll)ret * (ll)S <= (ll)R) return ret;
int l = (-R % S + S) % S, r = (-L % S + S) % S, y = solve(S, M, l, r); if(y == -1) return -1;
int x = ((ll)R + (ll)M * (ll)y) / (ll)S; if((ll)L <= (ll)S * (ll)x - (ll)M * (ll)y) return x;
return -1;
}
int main() {
freopen("solve.in", "r", stdin); freopen("solve.out", "w", stdout);
int T = read();
while(T--) {
int M = read(), S = read(), L = read(), R = read();
printf("%d
", solve(M, S, L, min(R, M - 1)));
}
return 0;
}