[Nowcoder] 中位数
题意:给定一个序列和一个长度,求序列中子区间长度\(>=len\)的最大的中位数。
中位数定义:if\((len\%2) num = {len + 1} \over {2}\),else \(num ={len} \over {2}\)
思路:套路题,二分答案x,将序列\(>=x\)的数标为1,其他标为-1,判断是否有就是看前缀最小和是否大于0即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
int n,m;
int a[maxn];
inline bool ok(int mid) {
int b[maxn];
int mn = 0x7fffffff;
for(int i = 1;i <= n; ++i) {
if(a[i] >= mid) {
b[i] = 1;
}
else b[i] = -1;
}
for(int i = 1;i <= n; ++i) {
if(i >= m) mn = min(mn,b[i - m]);
b[i] += b[i - 1];
if(i >= m && b[i] - mn > 0) return true;
}
return false;
}
int l = 0x3f3f3f3f;
int ans;
int r = -0x3f3f3f3f;
int main () {
scanf("%d %d",&n,&m);
for(int i = 1;i <= n; ++i) scanf("%d",&a[i]),l = min(l,a[i]),r = max(a[i],r);
while(l <= r) {
int mid = (l + r) >> 1;
if(ok(mid)) {
l = mid + 1;ans = mid;
}
else r = mid - 1;
}
printf("%d\n",ans);
return 0;
}