题目链接:https://nanti.jisuanke.com/t/41406

时间限制:1000毫秒 内存限制:262144K

Problem Description

As we all know, Honk has nn pools, numbered as 1 1 1 ~ n n n. There is a i a_i ai liters water in the i i i-th pool. Every day, Honk will perform the following operations in sequence.


  1. Find the pool with the most water (If there are more than one, choose one at random) and take one liter of water.
  2. Find the pool with the least water (If there are more than one, choose one at random) and pour one liter of water into the pool.
  3. Go home and rest (Waiting for the next day).

Please calculate the difference between the amount of water in the pool with the most water and the amount of water in the pool with the least water after the k k k days.

Input

The input consists of multiple test cases. The input is terminated by the end of file.The number of data sets will not exceed 40

The first line of each test case contains two integers n n n and k k k, which indicate the number of pools and the number of days to operate the pool.

The second line of each test case contains n n n integers, and the i i i-th number represent a i a_i ai indicating the initial amount of water in the i i i-th pool.

1 ≤ n ≤ 500000 1 \le n \le 500000 1≤n≤500000, 1 ≤ k ≤ 1 0 9 1 \le k \le 10^9 1≤k≤109, 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109.

Output

For each test case, print one line containing the answer described above.

样例输入1


4 100
1 1 10 10


样例输出1


1


样例输入2


4 3
2 2 2 2


样例输出2


0


解题思路

题意: 给你一些水池,k次操作,每次在水量最多的地方取1升水,然后倒到水量最少的地方,求最后最多水量和最少水量的差值。

思路: 我们可以先求出最后的平衡状态,如果k比较大,那么到达平衡状态的时候就是在一个地方取水和倒水。平衡状态有两种:


  1. 一种是总水量可以平分n个水池,那么差值就是0。例如,1 2 3 4 5,最后的平衡状态就是:3 3 3 3 3。
  2. 另外一种就是无法平均的,那么差值就是1。例如,1 3 4 5 6,最后的平衡状态就是:4 4 4 4 3。

而当其k很小,无法使其达到平衡状态的时候,我们就直接模拟,与平衡状态比较,将需要添水的放到一个数组里,然后从最小的开始模拟倒水,求出下边界,然后同样的过程,模拟取水,求出上边界,两者的差值即为答案。

Accepted Code:

/* 
* @Author: lzyws739307453
* @Language: C++
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 5;
int a[MAXN], b;
int sa[MAXN], sb[MAXN];
int main() {
int n, k;
while (~scanf("%d%d", &n, &k)) {
long long sum = 0, cnt = 0;
memset(sa, 0, sizeof(sa));
memset(sb, 0, sizeof(sb));
int cnta = 0, cntb = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
sum += a[i];
}
sort(a, a + n);
int m = sum % n, s = sum / n;
for (int i = 0; i < n; i++) {
b = s;
if (m - i > 0) b++;
if (a[i] < b) {
cnt += b - a[i];
sa[++cnta] = a[i];
}
else sb[++cntb] = a[i];
}
if (k >= cnt) {
printf("%d\n", m != 0);
continue;
}
int l, r, dep, res = k;
for (int i = 1; i <= cnta; i++) {
dep = 1ll * (sa[i + 1] - sa[i]) * i;
if (dep >= 0 && res > dep)
res -= dep;
else {
l = sa[i] + res / i;
break;
}
}
res = k;
for (int i = cntb; i >= 1; i--) {
long long dep = 1ll * (sb[i] - sb[i - 1]) * (cntb - i + 1);
if (res > dep)
res -= dep;
else {
r = sb[i] - res / (cntb - i + 1);
break;
}
}
printf("%d\n", r - l);
}
return 0;
}