• 杂题集萃[2]


    题目描述

    小N得到了一个非常神奇的序列A。

    这个序列长度为N,下标从1开始。

    A的一个子区间对应一个序列,可以由数对[l,r]表示,代表A[l], A[l + 1], ..., A[r]这段数。

    对于一个序列B[1], B[2], ..., B[k],定义B的中位数如下:

    1. 先对B排序。得到新的序列C。

    2. 假如k是奇数,那么中位数为$$C=[frac{K+1}{2}]$$假如k为偶数,中位数为$$C=[frac{K}{2}]$$。

    对于A的所有的子区间,小N可以知道它们对应的中位数。

    现在小N想知道,所有长度>=Len的子区间中,中位数最大可以是多少。

    输入描述:

    第一行输入两个数N,Len。

    第二行输入序列A,第i个数代表A[i]。

    输出描述:

    一行一个整数,代表所有长度>=Len的子区间中,最大的中位数。

    • 输入

    11 3
    4864 8684 9511 8557 1122 1234 953 9819 101 1137 1759 
    
    • 输出

    8684
    

    数据范围:

    30%: n <= 200
    60%: n <= 2000
    另外有20%:不超过50个不同的数
    100%:1<=Len<=n<=10^5, 1 <= a[i] <= 10^9

    题解

    二分前缀和

    code

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=100010;
    int n,m,i,j,k,a[N],b[N],t,l,r,mid;
    bool f(int k){
        for (int i=1;i<=n;i++) if (a[i]<k) b[i]=-1; else b[i]=1;
        for (int i=1;i<=n;i++) b[i]+=b[i-1];
    	int ans=b[m];t=0;
    	for (int i=m+1;i<=n;i++){
    		t=min(t,b[i-m]);
    		ans=max(ans,b[i]-t);
    	}
    	if (ans>0) return true; 
    	else return false;
    }
    int main(){
        scanf("%d%d",&n,&m);
    	for (i=1;i<=n;i++) scanf("%d",&a[i]);
        l=1;r=1000000000;while (l<r){
    		mid=(l+r)/2+1;
    		if (f(mid)) l=mid; 
    		else r=mid-1;
    	}
    	printf("%d
    ",l);
    	return 0;
    }
    
  • 相关阅读:
    函数的一些应用
    关于javascript的一些知识以及循环
    <记录学习>京东页面最后一天HTML以及css遇到的问题
    <记录学习>(前三天)京东页面各种注意点
    银行账号输入格式代码
    CSS兼容性常见问题总结
    移动端实现摇一摇并振动
    LESS使用方法简介(装逼神器)
    H5移动端性能优化
    BFC,IFC,GFC,FFC的定义及功能
  • 原文地址:https://www.cnblogs.com/Sparks-Pion/p/9651873.html
Copyright © 2020-2023  润新知