BZOJ 2600 IOI2011 ricehub 中位数

题目大意:给定一条道路上的n个稻田,要求建一个粮仓,并且选定一些稻田进行运输,这些稻田到粮仓的距离之和不能超过B,求最多能选择多少个稻田

维护一个队列,头指针从前到后扫一遍

如果发现尾指针到头指针这段稻田的中位数上建一个粮仓时距离之和超过了B,就调整尾指针

对距离维护一个前缀和 每次取中位数之后可以O(1)计算距离和

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
int n,length,ans,a[M];
long long limit,sum[M];
bool Check(int l,int r)
{
	int mid=l+( (r-l+1)>>1 );
	long long sum1=(long long)(mid-l)*a[mid]-(sum[mid]-sum[l]);
	long long sum2=(sum[r]-sum[mid])-(long long)(r-mid)*a[mid];
	return sum1+sum2>limit;
}
int main()
{
	int i,j;
	cin>>n>>length>>limit;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		sum[i]=sum[i-1]+a[i];
	}
	for(j=0,i=1;i<=n;i++)
	{
		while( Check(j,i) )
			++j;
		ans=max(ans,i-j);
	}
	cout<<ans<<endl;
	return 0;
}


你可能感兴趣的:(中位数,bzoj,IOI2011,BZOJ2600)