zoukankan      html  css  js  c++  java
  • 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;
    		l=0;r=sum/n+1;//左闭右开
    		while(r-l>1){
    			mid=(r+l)/2;
    			if(check2(mid))
    				l=mid;
    			else r=mid;
    		}
    		ll down=l;
    		printf("%lld
    ",up-down);
    	}
    }
    
  • 相关阅读:
    The Worm Turns
    Equations
    Snail’s trouble
    WuKong
    Codeforces 369 C Valera and Elections
    POJ 2186 Popular Cows
    Codefroces 366 D Dima and Trap Graph (最短路)
    Codefroces 366 C Dima and Salad(dp)
    Codefroces 374 B Inna and Sequence (树状数组 || 线段树)
    Codeforces 374 C Inna and Dima (DFS)
  • 原文地址:https://www.cnblogs.com/ucprer/p/11544522.html
Copyright © 2011-2022 走看看