题解 [AGC026B] rng_10s

· · 题解

多校联考考这个题,然后因为大样例给的太水了很多人因此挂分。

题意

A \ge B 时,A \gets A - B,如果此时 A \le CA \gets A + D

请问能否无限循环执行下去。

分析

首先分析几个比较容易判断的条件。

$D < B$ 时即使进入了循环也没有用,因为即使能加也不能使 $A$ 回到原来的水平。 对于剩下的情况,此时已经保证了 $A \ge B$,$D \ge B$。 一种显然会无限循环的情况是 $C \ge B-1$,因为当 $A < B$ 时必然满足 $A \le C$ 的情况,且 $D \ge B$,所以一定又会将 $A$ 加回 $A \ge B$ 的状态。 剩下的情况是绝对无解或有解的吗?并不是。 如果我们可以找到一个非负整数 $k$ 使得 $( a + k(d-b) ) \bmod b > c$,也就是说经过一定的操作后 $C < A < B$,那么就不能继续循环了。 将上面那个式子转化为同余方程 $kd \equiv x - a \pmod{b}$,需要找到一个 $x \in (c,b)$ 使得该同余方程有解。 根据裴蜀定理,同余方程有解的条件是 $\gcd(b,d) \mid (x-a)$,于是我们直接求最大的 $x$ 即可。 单次时间复杂度 $O(\log n)$。 ## 代码 ```cpp //the code is from chenjh #include<cstdio> #include<algorithm> using namespace std; typedef long long LL; LL a,b,c,d; void solve(){ scanf("%lld%lld%lld%lld",&a,&b,&c,&d); if(d<b||a<b) puts("No"); else{ if(c>=b-1) puts("Yes"); else{ LL g=__gcd(d,b); a%=b; LL x=(b-1-a)/g*g; puts((a+x)%b>c?"No":"Yes"); } } } int main(){ int T;scanf("%d",&T); while(T--) solve(); return 0; } ```