CodeForces - 1486D Max Median(二分)

题目链接

题目大意

  求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;
} 
上一篇:Linq扩展方法


下一篇:二分(Max Median)