cf671 B. 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