We all know the impressive story of Robin Hood. Robin Hood uses his archery skills and his wits to steal the money from rich, and return it to the poor.
There are n citizens in Kekoland, each person has c i coins. Each day, Robin Hood will take exactly 1 coin from the richest person in the city and he will give it to the poorest person (poorest person right after taking richest’s 1 coin). In case the choice is not unique, he will select one among them at random. Sadly, Robin Hood is old and want to retire in k days. He decided to spend these last days with helping poor people.
After taking his money are taken by Robin Hood richest person may become poorest person as well, and it might even happen that Robin Hood will give his money back. For example if all people have same number of coins, then next day they will have same number of coins too.
Your task is to find the difference between richest and poorest persons wealth after k days. Note that the choosing at random among richest and poorest doesn’t affect the answer.InputThe first line of the input contains two integers n and k (1 ≤ n ≤ 500 000, 0 ≤ k ≤ 109) — the number of citizens in Kekoland and the number of days left till Robin Hood’s retirement.
The second line contains n integers, the i-th of them is c i (1 ≤ c i ≤ 109) — initial wealth of the i-th person.OutputPrint a single line containing the difference between richest and poorest peoples wealth.Examples
Input
4 1
1 1 4 2
Output
2
Input
3 1
2 2 2
Output
0
题意:这是一个关于劫富济贫的问题,就是缩小贫富差距,有一个大侠每天可以偷一个富人的金币,给穷人,并且k天后便退休不在干了,问最后的贫富差距。
解题思路:要使最后的贫富差距最小,那么的话,也就是求最大值的最小值,最小值得最大值;所以求第一个的时候可以用一个二分法来求,第二个也用一个二分法来求,最后再相减即可。
解题步骤:
1)首先的对存入每个人贫富用sort函数进行从小到大进行排序,这样便知道开始时最大和最小的 ;
2)首先利用一次二分算法,将最大值的最小值找出来,也就是劫富济贫之后的最大值,第一富人;
3)再一次利用二分算法将最小值的最大值,也就是通过救济之后的穷人的钱财;
4)注意,劫富济贫的钱财不能超过天数,因为他每天只能偷一个;也就是每天只有一个金币流转;
#include <iostream>
#include <algorithm>
using namespace std;
int n;
long long k,a[500005];
int main()
{
while(cin>>n>>k)
{
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
int max=a[n-1],min=a[0];
int low=min,high=max;
while(low<=high)
{
int mid=(low+high)/2;
long long k1=0,c=0;
for(int i=0;i<n;i++)
{
if(a[i]>mid)
k1+=(a[i]-mid);
else c+=(mid-a[i]);
}
if(k1<=k&&c>=k1)
{
high=mid-1;
max=mid;
}
else low=mid+1;
}
low=0,high=a[n-1];
while(low<=high)
{
int mid=(low+high)/2;
long long k2=0,c1=0;
for(int i=0;i<n;i++)
{
if(a[i]<mid) k2+=(mid-a[i]);
else c1+=(a[i]-mid);
}
if(k2<=k&&c1>=k2)
{
low=mid+1;
min=mid;
}
else high=mid-1;
}
cout<<max-min<<endl;
}
return 0;
}