Minimizing Difference(CodeForces - 1244E )

Minimizing Difference

You are given a sequence a1,a2,…,an consisting of n integers.
You may perform the following operation on this sequence: choose any element and either increase or decrease it by one.
Calculate the minimum possible difference between the maximum element and the minimum element in the sequence, if you can perform the aforementioned operation no more than k times.

Input

The first line contains two integers n and k (2≤n≤105,1≤k≤1014) — the number of elements in the sequence and the maximum number of times you can perform the operation, respectively.
The second line contains a sequence of integers a1,a2,…,an (1≤ai≤109).

Output

Print the minimum possible difference between the maximum element and the minimum element in the sequence, if you can perform the aforementioned operation no more than k times.

Examples

Input
4 5
3 1 7 5
Output
2
Input
3 10
100 100 100
Output
0
Input
10 9
4 5 5 7 5 4 5 2 4 3
Output
1

给一个长度为n的序列,求序列中最大元素与最小元素的差,你被允许一个操作:
对某个元素进行加一或者减一,你可以最多进行k次操作,问序列的极差最小可以为多少,首先 极差=a[i] (max)-a[i] (min) 要是极差变小,只要是最大值与最小值尽可能的接近就好, 所以先排序,取出最小值和最大值,并且要看最大值元素有几个,最小值元素有几个,因为我们只可以进行k此操作,所以我们需要进行尽量的少的操作减小极差,举个列子 1 1… 7 显然极差是6,那么我们若要减小极差,可以使7减小或者1增大,若要让7减小只需要进行至少一次操作,若要让1增大至少需要两次操作,所以每次我们要进行操作时,先看最小元素和最大元素各有几个,对数量少的进行操作,直至最小值等于最大值,此时极差等于0,已达到最小,或者k次操作进行完。
代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100200];
int main()
{
    int n;
    ll k;
    scanf("%d%lld",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    sort(a,a+n);
    int minn=a[0],maxx=a[n-1];
    int l=0,r=n-1;
    while(minn!=maxx&&k>0)
    {
        ll len1=0,len2=0;
        int flag1=l,flag2=r;
        while(a[l]==minn)
            l++;
        len1=l;
        while(a[r]==maxx)
            r--;
        len2=n-1-r;
        if(len1<=len2)
        {

            r=flag2;
            ll  w=a[l]-minn;
            if(w*len1<=k)
            {
                minn=a[l];
                k-=w*len1;
            }
            else
            {
                minn=minn+k/len1;
                break;
            }
        }
        else
        {
            l=flag1;
            ll  w=maxx-a[r];
            if(w*len2<=k)
            {
                maxx=a[r];
                k-=w*len2;
            }
            else
            {
                maxx=maxx-k/len2;
                break;
            }
        }
    }

    int q=maxx-minn;
    printf("%d\n",q);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值