CF1594F Ideal Farm 题解

Description

给你三个整数 \(s,n,k\),问对于任意长度为 \(n\) 的且满足 \(\sum\limits_{i=1}^{n}a_i=s\)\(\forall a_i\in[1,n],a_i>0\) 的数列 \(a\) 是否都有 \(\exists l\in[1,n],r\in[l,n],\sum\limits_{i=l}^{r}a_i=k\)。如果是,输出 YES,否则输出 NO

多组数据,数据组数 \(T\le10^5\)\(1\le s,n,k\le10^{18},n\le s\)

Solution

提供一个更加简单的思路。

首先根据题意,显然当 \(s<k\) 时一定不满足条件,当 \(s=k\) 时一定满足条件。

来看 \(s>k\) 的情况。此时可以将问题转化为能否构造出一个数列使得 \(\forall l\in[1,n],r\in[l,n],\sum\limits_{i=l}^{r}a_i\ne k\)。由于需要满足 \(\forall a_i\in[1,n],a_i>0\),因此我们可以先把 \(a\) 数列的每个位置都先填上一个 \(1\)。此时观察这个数列,发现在 \(a_k\) 这个位置满足 \(\sum\limits_{i=1}^{k}a_i=k\),不符合我们构造数列的规则。对此我们可以将 \(a_k\) 的位置加上一个 \(k\),这样一来 \(a_1\)\(a_{k-1}\) 的值都是 \(1\)\(a_k\) 的值变成了 \(k+1\),这样前面 \(k\) 个数无法拼凑出 \(k\) 了。加上其它数也是可以的,但是 \(a_k\) 一定至少要变成 \(k+1\),否则还是可以拼凑出 \(k\)。进一步,我们可以发现,每当处于 \(k\) 的某个倍数 \(p\times k\) 时都会出现 \(\sum\limits_{i=p\times k-k+1}^{p\times k}a_i=k\) 的情况,这时候我们都需要将 \(a_{p\times k}\) 的值加上 \(k\)。当然在其它地方加上 \(k\) 也是可以的,但是根据贪心策略,显然在加 \(p\times k\) 处不会使总花费变多,是更优的。如果觉得有点抽象,可以看一下这张图:

\(a\) 数列 \(n\) 个位置包含 \(\lfloor\frac{n}{k}\rfloor\)\(k\) 的倍数。由于剩下的部分不到完整的 \(k\) 个数因此不用考虑。每次遇到一个 \(k\) 的倍数都要使那个位置上的数加上 \(k\),一共要加 \(\lfloor\frac{n}{k}\rfloor\times k\)。由于已经给 \(a\) 数列每个位置填了 \(1\),因此 \(s\) 的值还剩 \(s-n\)。如果 \(s-n\ge \lfloor\frac{n}{k}\rfloor\times k\),说明我们可以构造出反例,输出 NO,否则输出 YES

Code

#include<bits/stdc++.h>
#define LL long long
using namespace std;
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		LL s,n,k;
		scanf("%lld%lld%lld",&s,&n,&k);
		if(s<k) puts("NO");
		else if(s==k) puts("YES");
		else
		{
			if(s-n>=n/k*k) puts("NO");
			else puts("YES");
		}
	}
	return 0;
}
posted @   __Star_Sky  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示