题意:给出一个数组,找出长度>=k的subarray的中位数的最大值。
思路:
二分中位数,然后看原数组是否满足条件。
怎么判断呢?
对于数组的每个数,把小于当前数字的设为-1,大于当前数的设为1
然后由此求前缀和pre。
如果长度始终等于k,那么显然我们只要判断一个pre[i]-pre[i-k]>0就够了
然现在是长度>=k
那么我们就要引出一个新的数组minpre
也就是截至到当前的最小前缀和
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+5;
int a[maxn];
int pre[maxn];
int minpre[maxn];
int n,k;
bool check(int x)
{
for(int i=1;i<=n;i++){
pre[i]=pre[i-1]+(a[i]>=x?1:-1);
minpre[i]=min(minpre[i-1],pre[i]);
}
for(int i=k;i<=n;i++){
if(pre[i]-minpre[i-k]>0){
return 1;
}
}
return 0;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int l = 1,r = n;
int ans = -1;
while(l<=r)
{
int mid = (l+r)/2;
if(check(mid))
{
ans = mid;
l = mid+1;
}
else
{
r = mid-1;
}
}
cout<<ans<<endl;
}