【题意】给你n个数,k个操作,每次操作把最大的减一,最小的加上一,直到最大的减一变成最小的,那么再把这个减掉的1加回去。

【分析&解题思路】orz队友!!!这题其实就是个赤果果的模拟呀。考虑求最大值的时候,我们考虑从右边切,求最小值的时候考虑从左边切。这样切出来之后,必然就是左边低右边高的情况合法。那么左边右边高呢,其实这里只用判断sum%n是否为0即可,如果为0值为0,否则为1。

【AC代码】

#include <set>
#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define maxn 500010
int n,k,a[maxn];
ll sum;
int main(){
    sum=0;
    cin>>n>>k;
    for(int i=0;i<n;i++) scanf("%d",&a[i]),sum+=a[i];
    sort(a,a+n);
    ll maxx=a[n-1],minn=a[0];
    ll t=k;
    //切,从右往左
    for(int i=n-1;i>=0;i--){
        if(maxx>a[i]){
            ll temp = min(maxx-a[i],t/(n-i-1));
            t-=temp*(n-i-1);
            maxx-=temp;
        }
    }
    //补,从左向右
    t=k;
    for(int i=0; i<n; i++){
        if(minn<a[i]){
            ll temp = min(a[i]-minn,t/i);
            t-=temp*i;
            minn+=temp;
        }
    }
    //cout<<max(sum%n?1ll:0ll,maxx-minn)<<endl;
    printf("%I64d\n",max(sum%n?1ll:0ll,maxx-minn));
    return 0;
}