CF1594F-Ideal Farm【构造】
正题
题目链接:https://www.luogu.com.cn/problem/CF1594F
题目大意
给出\(n,s,k\),求是否所有的长度为\(n\)且和为\(s\)的正整数序列都有一段和为\(k\)的区间。
\(1\leq T\leq 10^5,1\leq n,s,k\leq 10^{18}\)
解题思路
可以考虑构造一个序列使得没有和为\(k\)的区间。
要求使得没有两个前缀和差值为\(k\),构造时显然前面的越小越好,因为如果前面的增大给后面的减小那么还不如直接让前面的减小,当我们在前缀和中填入\(1\sim k-1\)之后我们下一个由于\((0\sim k-1)+k\)都给封锁住了所以我们只能填\(2k\),然后可以继续往后填\(2k\sim 3k-1\),发现每隔\(k\)个就要加\(k+1\)。
也就是我们构造的序列是形如:\(1,1,1,1,...k+1,1,1,1,...k+1,1,1,1\)形式的,计算出前\(n\)个的最小和就好了。
然后交上去发现WA了,后来想了想当\(n<k\)时由于没有填上关键格所以需要特殊考虑,如果\(s=k\)时显然是无解的,否则\(n<k\)时填\(n-1\)个\(1\)然后填\(s-n+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;
}