【CodeForces】671 B. Robin Hood

【题目】B. Robin Hood

【题意】给定n个数字的序列和k次操作,每次将序列中最大的数-1,然后将序列中最小的数+1,求最终序列极差。n<=5*10^5,0<=k<=10^9,1<=ai<=10^9。

【算法】模拟

【题解】关键在于,增加和减少可以分开操作。

将数列排序,从小到大增加前面若干个数到同一个数直到k次,再从大到小减少后面若干个数到同一个数直到k次,就可以得到结果。

也可以不排序直接二分”同一个数”找到恰好k次的位置。

#include<cstdio>
#include<algorithm>
int n,k,a[500010];
void solve(){
    std::sort(a+1,a+n+1);
    int t=0,b=0,s=k;
    while(t<n&&1ll*t*(a[t+1]-b)<=s)s-=1ll*t*(a[t+1]-b),b=a[++t];
    b=s/t;s%=t;
    for(int i=1;i<=t;i++)a[i]=a[t]+b+(i>t-s);
    for(int i=1;i<=n;i++)a[i]=-a[i];
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    solve();solve();
    printf("%d",a[1]-a[n]);
    return 0;
}
View Code

 

posted @ 2017-12-21 16:51  ONION_CYC  阅读(233)  评论(0编辑  收藏  举报