CF1157D N Problems During K Days(简单构造)

时间:2023-03-09 08:42:41
CF1157D N Problems During K Days(简单构造)

题目

题目

原数据是水成啥样了,\(<\longrightarrow <=,>=\longrightarrow <=,\)这也能过 被\(hack\)后身败名裂

做法

简单的贪心吧

开始先填上\(1\)~\(k\),然后如果能全部\(+1\)就加:这样一定能为后面的构造创造出更多的可能(\(2\)倍的限制)

后面就找到能填的最小的位置反复填就行了

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=1e6+9;
LL n,k;
LL a[maxn];
int main(){
cin>>n>>k;
LL ret(0);
for(LL i=1;i<=k;++i) a[i]=i,ret+=a[i];
if(ret>n){
puts("NO"); return 0;
}
LL tmp(n-ret);
if(tmp>=k){
LL lun(tmp/k);
for(LL i=1;i<=k;++i) a[i]+=lun;
ret+=lun*k;
}
LL up(0);
while(true){
tmp=n-ret;
if(!tmp) break;
LL now(std::max(k-tmp+1,up));
if(a[now-1]*2<a[now]+1){
LL f(0);
for(LL j=now+1;j<=k;++j){
if(a[j-1]*2>=a[j]+1){
f=j;
break;
}
}
if(!f){
puts("NO"); return 0;
}
up=f;
for(LL j=f;j<=k;++j) ++a[j];
ret+=k-f+1;
}else{
for(LL i=now;i<=k;++i) ++a[i];
ret+=k-now+1;
}
}
puts("YES");
for(LL i=1;i<=k;++i) cout<<a[i]<<' ';
return 0;
}