3544:[ONTAK2010]Creative Accounting 贪心+迷の卡常数
BZOJ1811:[Ioi2005]mea 乱搞

BZOJ2600:[Ioi2011]ricehub 贪心+二分

shinbokuow posted @ Jan 15, 2015 08:50:47 AM in BZOJ with tags 贪心 , 1140 阅读

思路:

显然当我们选定一个米仓的位置后,选择的粮田的位置是一段连续区间.

我们不妨枚举枚举所有的粮田区间,于是我们发现在给定粮田区间时,最优的米仓位置必定是中位数,可以\(O(1)\)确定.

若我们枚举所有的区间,则是\(O(R^2)\)的.

于是我们考虑固定区间起点,则需要的花费显然随区间终点右移而单调不减.于是我们二分得到最优的区间终点即可.

时间复杂度\(O(nlogn)\).

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;
 
typedef long long LL;
 
#define N 100010
int a[N];
LL sum[N];
 
long long getsum(int l,int r){return sum[r]-sum[l-1];}
long long getinterval(int l,int r){
    if(l==r)return 0;
    if((r-l+1)&1){
        int midins=(l+r)>>1;
        return getsum(midins+1,r)-getsum(l,midins-1);
    }
    else{
        int midins=(l+r)>>1;
        return getsum(midins+1,r)-getsum(l,midins);
    }
}
 
int main(){
    int R,L;LL B;scanf("%d%d%lld",&R,&L,&B);
    register int i,j;for(i=1;i<=R;++i)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
     
    int l,r,mid,res=0;
    for(i=1;i<=R;++i){
        l=i,r=R;while(l<r){mid=(l+r+1)>>1;if(getinterval(i,mid)<=B)l=mid;else r=mid-1;}res=max(res,l-i+1);
    }
     
    printf("%d",res);
     
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter