【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次的位置。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }