标签: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. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。