A Modular Arithmetic Challenge
POJ - 3530 https://vjudge.net/problem/POJ-3530
Description
Given four positive integers M, D, L, R, your task is to find the minimal non-negative integer x which satisfies L ≤ ( D × x mod M ) ≤ R, where mod is the remainder operation
Input
The first line contains one number N – the number of test cases.(1 ≤ N ≤ 100)
Each of the following N lines contains four integers M, D, L, R ( 1≤ M, D, L, R ≤ 2,000,000,000)
Output
For each test case, print the minimal x. If there is no such x, print “-1” instead.
Sample Input
4
4 3 1 1
4 2 1 1
4 2 2 4
4 4 4 4
Sample Output
3
-1
1
-1
解题思路
对原式可以化成
L
≤
D
x
−
M
y
≤
R
L\le Dx-My\le R
L≤Dx−My≤R
分类讨论当y为0时如果LR之间可以有解就直接求解
当y不为0时原式进行转化
D
x
−
R
≤
M
y
≤
D
x
−
L
Dx-R\le My \le Dx-L
Dx−R≤My≤Dx−L
对这个式子如越小则一定有x越小为此求解最小
对这个式子两边取模则变为
−
R
%
D
≤
(
M
%
D
)
y
%
D
≤
−
L
-R\%D\le (M\%D)y\%D\le -L
−R%D≤(M%D)y%D≤−L
由此则将y的求解化为和求解x一样的形式了,递归求解得出答案即可
AC代码
#include<cstdio>
#include<iostream>
using namespace std;
typedef int Int;
#define int long long
int dfs(int m,int d,int L,int R)
{
if(L>R||!d) return -1;
if(R/d*d>=L) return (L-1)/d+1;
int x=dfs(d,m%d,((-R)%d+d)%d,((-L)%d+d)%d);
if(x==-1) return -1;
return (L-1+x*m)/d+1;
}
Int main()
{
int m,d,l,r;
int t;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld%lld",&m,&d,&l,&r);
r=min(m-1,r);
cout<<dfs(m,d,l,r)<<endl;
}
}