中位数

链接:https://www.nowcoder.com/acm/contest/172/A
来源:牛客网
 

题目描述

小N得到了一个非常神奇的序列A。这个序列长度为N,下标从1开始。A的一个子区间对应一个序列,可以由数对[l,r]表示,代表A[l], A[l + 1], ..., A[r]这段数。对于一个序列B[1], B[2], ..., B[k],定义B的中位数如下:

1. 先对B排序。得到新的序列C。

2. 假如k是奇数,那么中位数为。假如k为偶数,中位数为

对于A的所有的子区间,小N可以知道它们对应的中位数。现在小N想知道,所有长度>=Len的子区间中,中位数最大可以是多少。

输入描述:

第一行输入两个数N,Len。
第二行输入序列A,第i个数代表A[i]。

输出描述:

一行一个整数,代表所有长度>=Len的子区间中,最大的中位数。

示例1

输入

复制

11 3
4864 8684 9511 8557 1122 1234 953 9819 101 1137 1759 

输出

复制

8684

备注:

数据范围:
30%: n <= 200
60%: n <= 2000
另外有20%:不超过50个不同的数
100%:1<=Len<=n<=10^5, 1 <= a[i] <= 10^9

 

二分答案x,把大于等于x的记为1,否则记为-1,计算长度大于等于L的最大字段和,若其大于0,则存在。

#include<iostream>
#include<algorithm>
#include<cstring>
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=100005;
int n,L;
int a[MAXN],b[MAXN],c[MAXN];
bool check(int x)
{
	int i,j;
	f(i,1,n){
		if(a[i]<b[x]){
			c[i]=-1;
		}
		else c[i]=1;
		c[i]+=c[i-1];
	}
	int las=0,ans=c[L];
	f(i,L+1,n){
		las=min(las,c[i-L]);
		ans=max(ans,c[i]-las);
		if(ans>0) return true;
	}
	return false;
}
int main()
{
	int i,j;
	int l,r; 
	cin>>n>>L;
	f(i,1,n){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	l=1;r=n;
	while(l<r){
		int mid=(l+r+1)>>1;
		if(check(mid)){
			l=mid;
		}
		else r=mid-1;
	}
	cout<<b[l]<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值