codeforces672Robin Hood(经典二分)
2016-07-02 20:52
211 查看
怎么都没想到是二分,我真弱爆了。
二分求出k天后最小的人的财富,
理由:
最小的人的财富必然小于或等于平均数向下取整(记为la),
所以范围在0~la之间,二分答案。
再用二分求出k天后最大的人的财富。相减即得答案。
注意:sum等可能会爆int.
二分求出k天后最小的人的财富,
理由:
最小的人的财富必然小于或等于平均数向下取整(记为la),
所以范围在0~la之间,二分答案。
再用二分求出k天后最大的人的财富。相减即得答案。
注意:sum等可能会爆int.
#include <iostream> #include <algorithm> #include <string.h> #include <stdio.h> using namespace std; #define ms(X) memset(X,0,sizeof(X)) #define Inf 0x3fffffff typedef long long ll; int arr[502000]; int main(int argc, char const *argv[]) { int n,k; ll sum=0; cin>>n>>k; for(int i=0;i<n;i++) {scanf("%d",arr+i); sum+=(ll)arr[i]; } int l=0,r=(int)(sum/n)+1,ans1=0,mid; while(l<r) { mid=(l+r)>>1; ll tmp=0; for(int i=0;i<n;i++) if(mid>arr[i]) tmp+=mid-arr[i]; if(tmp<=k) ans1=mid,l=mid+1; else r=mid; } l=(int)((sum+n-1)/n),r=Inf; int ans2=0; while(l<r) { mid=((r-l)>>1)+l; ll tmp=0; for(int i=0;i<n;i++) if(mid<arr[i]) tmp+=arr[i]-mid; if(tmp<=k) ans2=mid,r=mid; else l=mid+1; } printf("%d\n",ans2-ans1 ); return 0; }
相关文章推荐
- VS2013使用技巧
- 【折腾日记GEN8_2】ESXI的安装
- Android之Fragment的使用(一)
- ActiveMQ 使用
- Problem4-1011
- Qt学习笔记3---QMainWindow使用
- Java计算图的匹配率
- PAT - 甲级 - 1008. Elevator (20)1008. Elevator (20)
- 【poj】3660 Cow Contest【floyd传递闭包】
- 学习Discuz! X3.2记录:快速回复插件的最后效果动画
- DNS 原理入门
- Loading...
- 【C/C++】求最大公约数的三种方法
- mysql 根据子类id查询所有父类id
- node.js跨域请求实现和.net框架的通讯
- 学习Discuz! X3.2记录:快速回复插件,通过js使选择的下拉列表填充到回帖内容中
- AddressBook获取用户信息
- 最短路经典例题 codevs 1557 热浪
- 基于Java实现简单Http服务器
- UVa1374(快速幂)