题意
每次你要让最大数减一,然后让最小数加一
然后操作k次
问你最大值减去最小值是多少
题解:
首先这道题模拟是可以的,但是太麻烦了……
所以还是直接二分就好了
二分一个最小值
然后再二分一个最大值
因为你会加k,使得小于那个最小值的数都加成为大于等于他的数
你会减去k,使得大于那个数,都降为小于等于的那个数
所以直接二分就完啦
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-9
#define maxn 1000100
#define MOD 1000000007
int n;
long long m;
long long a[maxn];
int main()
{
int t,C = 1;
//scanf("%d",&t);
while(scanf("%d%d",&n,&m) != EOF)
{
long long sum = 0;
for(int i = 0; i < n; i++)
{
scanf("%lld",&a[i]);
sum += a[i];
}
sort(a,a+n);
long long mx,mi;
if(sum % n == 0)
mx = mi = sum / n;
else
{
mi = sum / n;
mx = mi + 1;
}
long long l = mx,r = 1e9;
long long ans1,ans2;
while(l <= r)
{
long long mid = (l+r)>>1;
long long ssum = 0;
for(int i = n-1; i >= 0; i--)
{
if(a[i] > mid)
ssum += a[i] - mid;
else
break;
}
if(ssum <= m)
{
r = mid - 1;
ans1 = mid;
}
else
l = mid + 1;
}
l = 0,r = mi;
while(l <= r)
{
long long mid = (l+r)>>1;
long long ssum = 0;
for(int i = 0; i < n; i++)
{
if(a[i] < mid)
ssum += mid - a[i];
else
break;
}
if(ssum > m)
r = mid - 1;
else
{
l = mid + 1;
ans2 = mid;
}
}
//printf("%lld %lld\n",ans1,ans2);
printf("%lld\n",ans1-ans2);
}
return 0;
}