HZOI20190814 B 不等式

不等式

题目大意:求解满足$L \leqslant(S×x)mod M\leqslant R$的x最小正整数解,无解输出-1

几种部分分:

$L==R$,就是$ex_gcd$;

解在$1e6$以内:搜索

但是卓越的我们一定是要写满分代码的,所以我们上迷一样的正解

观察这个式子:$L \leqslant(S×x)mod M\leqslant R$

我们把它化一下:$L \leqslant Sx-My\leqslant R$

以y为主元:$-L \leqslant My-Sx\leqslant -R$

化成取模的形式:$-L mod S \leqslant (M×y)mod S \leqslant -R mod S$

我们要保证L,R是正数,则-L变为(-L%S+S)%S,R同理

那我们就可以愉快的dfs了

设4个参数,S,M,L,R,判断边界:

$L==0,return 0$

$L>R||L>=M||S%M==0$ $return -1$

然后$S=S%M$,这时$x=\frac{L-1}{S}+1$,判断x是否满足

这是$y=dfs(M,S,-R,-L)$,如果$y==-1$,不合法

若合法,则$x=\frac{R+M×y}{S}$,判断是否合法,合法返回x,不合法返回-1。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
int t,m,s,l,r;
int dfs(int m,int s,int l,int r){
	if(l>r||l>=m||s%m==0) return -1;
	if(l==0) return 0;
	s%=m;
	int x=(l-1)/s+1;
	if(s*x<=r) return x;
	int y=dfs(s,m,(-r%s+s)%s,(-l%s+s)%s);
	if(y==-1) return -1;
	x=(r+m*y)/s;
	if(s*x-m*y>=l) return x;
	return -1;
}
signed main(){
	scanf("%lld",&t);
	while(t--){
		scanf("%lld%lld%lld%lld",&m,&s,&l,&r);
		printf("%lld\n",dfs(m,s,l,min(r,m-1)));
	}
	return 0;
}

 

posted @ 2019-08-14 21:43  xukl21  阅读(132)  评论(0编辑  收藏  举报