zoukankan      html  css  js  c++  java
  • [构造]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
    ";
    		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
    ";
    	}
    	else
    	{
    		cout << "YES
    ";
    		for(int i = 0; i < n; ++i)
    			cout << arr[i] << ' ';
    	}
    	
    		
        return 0;
    }
  • 相关阅读:
    使用POI读写Word doc文件
    用纯css改变下拉列表select框的默认样式
    深入探究JFreeChart
    arcgis api for javascript中使用proxy.jsp
    【Itext】7步制作Itext5页眉页脚pdf实现第几页共几页
    iText5报表_页眉与页脚
    JFreeChart柱状图单组柱子的不同颜色显示
    如何自定义FusionCharts图表上的工具提示?
    span 文本内容超过宽度自动换行
    JS正则表达式验证账号、手机号、电话和邮箱
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270369.html
Copyright © 2011-2022 走看看