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]<<" ";
}

相关文章: