码迷,mamicode.com
首页 > 其他好文 > 详细

不等式

时间:2018-02-24 16:50:56      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:turn   文件   str   sdi   put   bit   --   input   amp   

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;
}

不等式

标签:turn   文件   str   sdi   put   bit   --   input   amp   

原文地址:https://www.cnblogs.com/aziint/p/8466088.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!