不等式
题目大意:求解满足$L leqslant(S×x)mod Mleqslant R$的x最小正整数解,无解输出-1
几种部分分:
$L==R$,就是$ex_gcd$;
解在$1e6$以内:搜索
但是卓越的我们一定是要写满分代码的,所以我们上迷一样的正解
观察这个式子:$L leqslant(S×x)mod Mleqslant R$
我们把它化一下:$L leqslant Sx-Myleqslant R$
以y为主元:$-L leqslant My-Sxleqslant -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 ",dfs(m,s,l,min(r,m-1))); } return 0; }