题目大意
求n个数中长度不小于k的子段的最大中位数
解题思路
考虑一下单调性,如果一个数使一个子段的中位数,那么在这个子段里面不小于他的数肯定大于k/2,我们如果二分这个数的大小的话,很明显是有单调性的。check的话,就把不小于二分的数的位置设为1,否则为-1,然后用前缀和处理,在当前位置-k之前的地方找一个最小值,然后判断当前位置减去这个最小值是否大于0即可。
代码
const int maxn = 2e5+10;
const int maxm = 2e5+10;
int sum[maxn], arr[maxn], n, k;
bool check(int x) {
for (int i = 1; i<=n; ++i) {
sum[i] = sum[i-1];
if (arr[i]>=x) ++sum[i];
else --sum[i];
}
int maxx = 0, minn = INF;
for (int i = k; i<=n; ++i) {
minn = min(minn, sum[i-k]);
maxx = max(maxx, sum[i]-minn);
}
return maxx > 0;
}
int main() {
cin >> n >> k;
for (int i =1; i<=n; ++i) cin >> arr[i];
int l = 1, r = n;
while(l<r) {
int mid = (l+r+1)>>1;
if (check(mid)) l = mid;
else r = mid-1;
}
cout << l << endl;
return 0;
}