Description
给出两个整数 $ n \(,\) k $ 你需要构造出一个有 \(k\) 项的数列 $ A $ 满足以下条件:
- 对于任意的 $ i\in [1,k] $ 有 $ A_i>0 $
- 对于任意的 $ i\in (1,k] $ 应当有 $ A_{i-1}<A_i\le2A_{i-1} $
- $ \sum\limits_{i=1}^kA_i=n $
Solution
首先我们可以构造一个等差数列 \(a_i=i\),如果此时 \(s>n\) 则必然无解
考虑先对每个位置加上 \([\frac {n-s} k]\),剩下 \((n-s) \bmod k\) 要加
考虑到 \(k\) 很小,我们从右往左依次枚举位置,每次暴力加一个后缀,倒序循环 \(+1\) 即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n,k,a[N];
signed main() {
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=k;i++) a[i]=i, n-=i;
if(n<0) {
cout<<"NO";
return 0;
}
int d=n/k;
for(int i=1;i<=k;i++) a[i]+=d, n-=d;
while(n>0) {
for(int i=k;i>=1 && n;--i) if(a[i-1]<a[i]+1 && a[i]+1<=2*a[i-1]) ++a[i],--n;
if(n && a[k]+1>2*a[k-1]) {
cout<<"NO";
return 0;
}
}
cout<<"YES"<<endl;
for(int i=1;i<=k;i++) cout<<a[i]<<" ";
}