[构造]D. N Problems During K Days
Polycarp has to solve exactly nn problems to improve his programming skill before an important programming competition. But this competition will be held very soon, most precisely, it will start in kk days. It means that Polycarp has exactly kk days for training!
Polycarp doesn't want to procrastinate, so he wants to solve at least one problem during each of kk days. He also doesn't want to overwork, so if he solves xx problems during some day, he should solve no more than 2x2x problems during the next day. And, at last, he wants to improve his skill, so if he solves xx problems during some day, he should solve at least x+1x+1 problem during the next day.
More formally: let [a1,a2,…,ak][a1,a2,…,ak] be the array of numbers of problems solved by Polycarp. The ii-th element of this array is the number of problems Polycarp solves during the ii-th day of his training. Then the following conditions must be satisfied:
- sum of all aiai for ii from 11 to kk should be nn;
- aiai should be greater than zero for each ii from 11 to kk;
- the condition ai<ai+1≤2aiai<ai+1≤2ai should be satisfied for each ii from 11 to k−1k−1.
Your problem is to find any array aa of length kk satisfying the conditions above or say that it is impossible to do it.
Input
The first line of the input contains two integers nn and kk (1≤n≤109,1≤k≤1051≤n≤109,1≤k≤105) — the number of problems Polycarp wants to solve and the number of days Polycarp wants to train.
Output
If it is impossible to find any array aa of length kk satisfying Polycarp's rules of training, print "NO" in the first line.
Otherwise print "YES" in the first line, then print kk integers a1,a2,…,aka1,a2,…,ak in the second line, where aiai should be the number of problems Polycarp should solve during the ii-th day. If there are multiple answers, you can print any.
题意 n个数m个空 求得一序列满足 a[i - 1] * 2 >= a[i] > a[i - 1]
解题思路, 先构造一个和最接近n的连续序列
则这个连续序列和n的差必然会小于m
然后从尾按题目要求贪心填即可, 填补了则无解
代码:
/*
Zeolim - An AC a day keeps the bug away
*/
//pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
//typedef tree <long long, null_type, less <long long>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 10;
const ll MOD = 1e9 + 7;
ll n, m, arr[MAXN];
bool check(ll x)
{
return ( (x + x + n - 1) * n / ll(2) <= m);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
//freopen("D://test.in", "r", stdin);
//freopen("D://test.out", "w", stdout);
cin >> m >> n;
int fst = 1, lst = m, mid, ans = 1;
if(!check(1))
{
cout << "NO\n";
return 0;
}
while(fst <= lst)
{
mid = (fst + lst) / 2;
if(check(mid))
fst = mid + 1, ans = mid;
else
lst = mid - 1;
}
while(check(ans + 1))
++ans;
for(int i = 0; i < n; ++i)
arr[i] = i + ans, m -= arr[i];
for(int i = n - 1; i >= 0 && m; --i)
{
if(arr[i - 1] * 2 - arr[i] >= m)
{
arr[i] += m, m = 0;
break;
}
else
{
m -= (arr[i - 1] * 2 - arr[i]);
arr[i] = arr[i - 1] * 2;
}
}
if(m)
{
cout << "NO\n";
}
else
{
cout << "YES\n";
for(int i = 0; i < n; ++i)
cout << arr[i] << ' ';
}
return 0;
}