BZOJ2600:[Ioi2011]ricehub 贪心+二分
思路:
显然当我们选定一个米仓的位置后,选择的粮田的位置是一段连续区间.
我们不妨枚举枚举所有的粮田区间,于是我们发现在给定粮田区间时,最优的米仓位置必定是中位数,可以\(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;
}
评论 (0)