Codeforces Round #703 (Div. 2) D. Max Median

Max Median

Insert picture description here
Examples

input

5 3
1 2 3 2 1

output

2

input

4 2
1 2 3 4

output

3

Insert picture description here
General idea

Given a sequence a of length n, find the maximum value of the median of all consecutive subsequences of a whose length is greater than or equal to k.

analysis

Since 1<=a i <=n, the median value is 1~n. If x is determined to be a median, then the maximum value of the median must be >=x, which means the median The maximum value of is monotonic, so consider using dichotomy. Let the left end point be l, the right end point be r, the initial condition l=1, r=n, each time mid=(l+r+1)>>1, the key to the problem lies in how to judge whether there is a median> =mid, a clever approach is used here, marking all numbers less than mid as -1, and numbers greater than or equal to mid as 1, so that a sequence containing only 1 and -1 is obtained. If the median of an interval >= mid, then the sum of this interval (the interval after conversion to 1 and -1) must be> 0. According to this conclusion, the prefix sum is also required, because the sequence length is greater than or equal to k , So it is necessary to find whether all the intervals whose length is greater than or equal to k have a sum greater than 0, and the prefix minimum is also used here for optimization.

Time complexity O(nlog(n))

AC code

#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;
int a[N];
int b[N];
int n,k;

bool check(int mid)
{
    
    
	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++) b[i]+=b[i-1];
	int flag=0;
	int mn=0;  //最小值
	for(int i=k;i<=n;i++)
	{
    
    
		mn=min(mn,b[i-k]);
		if(b[i]-mn>0)
		{
    
    
			flag=1;
			break;
		}
	}
	return flag;
}

int main() 
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[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;
}

note

Here mid=(l+r+1)>>1 is to avoid infinite loops, which is caused by the rounding of bit operations.

Guess you like

Origin blog.csdn.net/weixin_46155777/article/details/113873722