题解:一道简单题,之前一直想歪了,set,优先队列都试过,简直年轻,其实直接两次二分就行了,一次二分最小值,一次二分最大值。(注意上下界)
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
typedef long long ll;
#define inf 1000000000
#define mod 1000000007
#define maxn 500005
#define PI 3.1415926
#define lowbit(x) (x&-x)
#define eps 1e-9
ll a[maxn], n, k;
bool check1(ll x)
{
int i;
ll res = 0;
for (i = 1;i <= n;i++)
if (a[i] < x)
res += x - a[i];
if (res <= k)
return 1;
return 0;
}
bool check2(ll x)
{
int i;
ll res = 0;
for (i = 1;i <= n;i++)
if (a[i] > x)
res += a[i] - x;
if (res <= k)
return 1;
return 0;
}
int main(void)
{
ll i, j, ans1, ans2, tmp, l, r, sum, mid;
while (scanf("%lld%lld", &n, &k) != EOF)
{
ans1 = 0;sum = 0;ans2 = 0;
for (i = 1;i <= n;i++)
scanf("%lld", &a[i]), sum += a[i];
ll mx = sum / n;l = 1, r = mx;
while (l <= r)
{
mid = (l + r) / 2;
if (check1(mid))
{
ans1 = mid;
l = mid + 1;
}
else
r = mid - 1;
}
if (sum%n) mx++;
l = mx;r = sum;
while (l <= r)
{
mid = (l + r) / 2;
if (check2(mid))
{
ans2 = mid;
r = mid - 1;
}
else
l = mid + 1;
}
printf("%lld\n", ans2 - ans1);
}
return 0;
}