当前位置: 首页 > 工具软件 > Farm > 使用案例 >

CF1594F-Ideal Farm【构造】

荀增
2023-12-01

正题

题目链接:https://www.luogu.com.cn/problem/CF1594F


题目大意

给出 n , s , k n,s,k n,s,k,求是否所有的长度为 n n n且和为 s s s的正整数序列都有一段和为 k k k的区间。

1 ≤ T ≤ 1 0 5 , 1 ≤ n , s , k ≤ 1 0 18 1\leq T\leq 10^5,1\leq n,s,k\leq 10^{18} 1T105,1n,s,k1018


解题思路

可以考虑构造一个序列使得没有和为 k k k的区间。

要求使得没有两个前缀和差值为 k k k,构造时显然前面的越小越好,因为如果前面的增大给后面的减小那么还不如直接让前面的减小,当我们在前缀和中填入 1 ∼ k − 1 1\sim k-1 1k1之后我们下一个由于 ( 0 ∼ k − 1 ) + k (0\sim k-1)+k (0k1)+k都给封锁住了所以我们只能填 2 k 2k 2k,然后可以继续往后填 2 k ∼ 3 k − 1 2k\sim 3k-1 2k3k1,发现每隔 k k k个就要加 k + 1 k+1 k+1

也就是我们构造的序列是形如: 1 , 1 , 1 , 1 , . . . k + 1 , 1 , 1 , 1 , . . . k + 1 , 1 , 1 , 1 1,1,1,1,...k+1,1,1,1,...k+1,1,1,1 1,1,1,1,...k+1,1,1,1,...k+1,1,1,1形式的,计算出前 n n n个的最小和就好了。

然后交上去发现WA了,后来想了想当 n < k n<k n<k时由于没有填上关键格所以需要特殊考虑,如果 s = k s=k s=k时显然是无解的,否则 n < k n<k n<k时填 n − 1 n-1 n1 1 1 1然后填 s − n + 1 s-n+1 sn+1即可。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll T,s,n,k;
signed main()
{
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld",&s,&n,&k);
		if(n<k){
			if(s==k)puts("YES");
			else puts("NO");
			continue;
		}
		ll w=n/k*2ll*k+n%k;
		if(s<w)puts("YES");
		else puts("NO");
	}
	return 0;
}
 类似资料: