ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

cf671 B. Robin Hood

2022-06-13 01:31:24  阅读:126  来源: 互联网

标签:cf671 int ll mid 最小值 sum 0ll Robin Hood


题意:

给定数组,每次操作把一个最大数-1,然后把一个最小数-1。注意有可能某次操作改的是同一个数。问 k 次操作后的极差

思路:

两种操作是独立的,可以先执行全部的+1再执行全部的-1。前者使最大值(非严格)减小,后者使最小值增大

因此可以先二分找最小的最大值,再二分找最大的最小值,答案是两者之差

即使 k 为无穷大,在最大值变成平均数上取整同时最小值变为平均数下取整之后整个数组就不会改变。二分的上下界要注意一下

void sol() {
    int n, k; cin >> n >> k;
    vector<int> a(n); for(int &x : a) cin >> x;

    ll l, r, sum = accumulate(all(a), 0ll);
    l = (sum+n-1)/n, r = 1e9;
    while(l < r) { //最小的最大数
        ll mid = (l + r) / 2;
        ll s = 0; for(int &x : a) s += max(0ll, x - mid);
        if(k >= s) r = mid; else l = mid + 1;
    }
    ll mx = l;
    l = 1, r = sum/n;
    while(l < r) { //最大的最小数
        ll mid = (l + r + 1) / 2;
        ll s = 0; for(int &x : a) s += max(0ll, mid - x);
        if(k >= s) l = mid; else r = mid - 1;
    }
    ll mn = l;
    
    cout << mx - mn;
}

标签:cf671,int,ll,mid,最小值,sum,0ll,Robin,Hood
来源: https://www.cnblogs.com/wushansinger/p/16369435.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有