不等式

Description

\(z\)热衷于数学。

今天数学课的内容是解不等式: \(L\le S \times x\le R\) 。小 \(z\) 心想这也太简单了,不禁陷入了深深的思考:加入已知 \(L,R,S,M\) ,满足 \(L\le (S\times 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\%\) 的数据中 \(T\le100,M,S,L,R\le10^9\)

Solution

来看原式子 $$L\le (S\times x) \ mod \ M \le R$$ 改写为 $$L\le S\times x - M\times y\le R$$ 设 \(y\) 为主元 $$-R+S\times x \le M\times y \le R + S\times x$$ 还原为取模形式 $$-R \ mod \ S \le (M\times 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\n", solve(M, S, L, min(R, M - 1)));
	}
	return 0;
}
posted @ 2018-02-24 15:39  aziint  阅读(224)  评论(1编辑  收藏  举报
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.