• [CSP-S模拟测试]:不等式(数学)


    题目描述

    小$z$热衷于数学。
    今天数学课的内容是解不等式:$Lleqslant S imes xleqslant R$。小$z$心想这也太简单了,不禁陷入了深深的思考:假如已知$L,R,S,M$,满足$Lleqslant (S imes x)mod Mleqslant R$的最小正整数该怎么求呢?


    输入格式

    第一行包含一个整数$T$,表示数据组数,接下来是$T$行,每行为四个正整数$M,S,L,R$。


    输出格式

    对于每组数据,输出满足要求的$x$值,若不存在,输出$-1$。


    样例

    样例输入:

    1
    5 4 2 3

    样例输出:

    2


    数据范围与提示

    $30\%$的数据中保证有解并且答案小于等于${10}^6$;
    另外$20\%$的数据中保证$L=R$;
    $100\%$的数据中$Tleqslant 100,M,S,L,Rleqslant {10}^9$。


    题解

    $30\%$算法:

    直接暴力枚举即可。

    $20\%$算法:

    $L=R$的情况直接用$exgcd$即可轻松解决。

    $100\%$算法:

    先设$0<L,Rleqslant <M,0<S<M$。

    显然所存在一个$S$的倍数$S imes x$满足$Lleqslant S imes xleqslant R$,那么此时的答案就是$x$。

    若不存在,不妨将式子$Lleqslant (S imes x)mod Mleqslant R$改写成$Lleqslant S imes x-M imes yleqslant R$。

    进一步改写成以$y$为主元,即$-Rleqslant M imes y-S imes xleqslant -L$。

    接着将其还原为取模的形式:$(-Rmod S)leqslant (M imes y)mod Sleqslant (-Lmod S)$。

    求出最小的满足上式的$y$值即可简介求出最小的$x$值(区间$[L,R]$中没有$S$的倍数)。

    建议调用递归函数解决问题,降低代码复杂度。

    时间复杂度:$Theta($玄学$)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    long long M,S,L,R;
    long long dfs(long long m,long long s,long long l,long long r)
    {
    	if(l>r||m<l)return -1;
    	if(((l-1)/s+1)*s<=r)return (l-1)/s+1;
    	long long flag;
    	if((flag=dfs(s,m%s,(-r%s+s)%s,(-l%s+s)%s))==-1)return -1;
    	if(l+m*flag<=(m*flag+r)/s*s)return (m*flag+r)/s;
    	return -1;
    }
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld%lld%lld",&M,&S,&L,&R);
    		printf("%lld
    ",dfs(M,S%M,L,min(R,M-1)));
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    MySQL之存储引擎
    MySQL之触发器
    MySQL之存储过程
    MySQL之自定义函数
    MySQL之视图
    三种方式安装mariadb-10.3.18
    Linux创建智能DNS
    CentOS 7 搭建Cobbler实现自动化安装系统
    搭建PXE实现自动化安装系统
    编译安装dropbear
  • 原文地址:https://www.cnblogs.com/wzc521/p/11366169.html
Copyright © 2020-2023  润新知