Honk's pool(二分模板题)
Posted ucprer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Honk's pool(二分模板题)相关的知识,希望对你有一定的参考价值。
题意:有n个水池,每个水池有a[i]单位水,有k次操作,每次操作将水量最多的水池减少一单位水,水量最少的水池增加一单位水,问最后水量最大的水池和水量最少的水池相差的水量。
思路:二分最后的最大水量和最小水量,特别的,模拟一下可以发现如果总水量sum%n==0,则最大值的下界和最小值的上界均为sum/n,若sum%n!=0,则最大值的下界为sum/n+1,最小值上界为sum/n。二分时注意选取区间是左闭右开还是左开右闭。
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
ll a[maxn];
ll n,k;
bool check1(ll p)
ll res=0;
for(int i=1;i<=n;i++)
if(a[i]>p) res+=a[i]-p;
if(res<=k) return 1;
else return 0;
bool check2(ll p)
ll res=0;
for(int i=1;i<=n;i++)
if(a[i]<p) res+=p-a[i];
if(res<=k) return 1;
else return 0;
int main()
while(~scanf("%lld%lld",&n,&k) )
ll sum=0;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
sum+=a[i];
ll l,r,mid;//左开右闭区间
r=1e9+9;
if(sum%n==0)
l=sum/n-1;
else l=sum/n;
while(r-l>1)
mid=(r+l+1)/2;
if(check1(mid))
r=mid;
else l=mid;
ll up=r;//>=k
l=0;r=sum/n+1;//左闭右开
while(r-l>1)
mid=(r+l+1)/2;
if(check2(mid))
l=mid;
else r=mid;
ll down=l;
printf("%lld\n",up-down);
以上是关于Honk's pool(二分模板题)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3966 Aragorn's Story(模板题)树链剖分+线段树
D. Arpa's weak amphitheater and Mehrdad's valuable Hoses 分组背包模板题