【数学】AtCoder Grand Contest 026 rng_10s

题意:

一家商店里有A瓶饮料,有一个老逗逼每天白天都会来到商店,磕B瓶饮料,到了晚上,当商店老板发现店里的饮料少于C瓶时,就会购入D瓶。
现在这个老逗逼想知道能不能无限地嗑下去(即每天都能磕B瓶)。


分析:

首先,有几个显而易见的特判:
1、 A &lt; B A &lt; B A<B,那么第一天就不够了
2、 D &lt; B D &lt; B D<B,那么无论商店老板怎么补,都补不赢这个老逗逼磕的速度。
3、在上述条件都不满足的情况下,如果 C + 1 ≥ B C+1\geq B C+1B,那么这个老逗逼永远不可能磕完。

现在考虑一下一般情况。
其实我们无非就是求
C &lt; A − x × B + y × D &lt; B C&lt;A-x\times B+y\times D&lt;B C<Ax×B+y×D<B x , y x,y x,y是否有解。

移一下项,变成了
A − B &lt; x × B − y × D &lt; A − C A-B&lt;x\times B-y\times D&lt;A-C AB<x×By×D<AC是否有解。

这时就很简单了, x × B − y × D x\times B-y\times D x×By×D能够凑出的数必然是 g c d ( B , D ) gcd(B,D) gcd(B,D)的倍数。(学过拓欧的应该都知道)

无非就是求 ( A − B , A − C ) (A-B,A-C) (AB,AC)中是否有 g c d ( B , D ) gcd(B,D) gcd(B,D)的倍数。

就是判断 ⌊ A − C − 1 g c d ( B , D ) ⌋ − ⌊ A − B g c d ( B , D ) ⌋ ≥ 0 \lfloor \frac {A-C-1} {gcd(B,D)}\rfloor - \lfloor \frac {A-B} {gcd(B,D)}\rfloor \geq 0 gcd(B,D)AC1gcd(B,D)AB0而已,满足即可能喝完,不满足则不可能。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
int n;
ll a,b,c,d;
ll gcd(ll x,ll y){
	if(y==0)
		return x;
	return gcd(y,x%y);
}
int main(){
	SF("%d",&n);
	while(n--){
		SF("%lld%lld%lld%lld",&a,&b,&c,&d);
		if(a<b){
			PF("No\n");
			continue;
		}
		if(b>d){
			PF("No\n");
			continue;
		}
		if(c+1>=b){
			PF("Yes\n");
			continue;
		}
		ll g=gcd(b,d);
		if((a-c-1ll)/g-(a-b)/g>0)
			PF("No\n");
		else
			PF("Yes\n");
	}
} 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值