zoukankan      html  css  js  c++  java
  • 牛客noip前集训营(第一场)提高T1

    链接:https://www.nowcoder.com/acm/contest/172/A
    来源:牛客网

    题目描述

    小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是奇数,那么中位数为。假如k为偶数,中位数为
    对于A的所有的子区间,小N可以知道它们对应的中位数。现在小N想知道,所有长度>=Len的子区间中,中位数最大可以是多少。

    输入描述:

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

    输出描述:

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

    输入

    复制
    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

    题目要求求区间最大中位数。

    最暴力的方法就是枚举每一个区间,然后将区间排序,查询中位数。

    稍微有话一下上边做法,就维护一个单调序列,查询中位数。

    然后看到网上还有一种做法,查询中位数当做查询区间第k大的数,用到了什么叫划分树的东西,枚举区间然后查询,貌似是一有80分。

    正解二分答案+前缀和:

    既然要二分答案,就需要序列有序,那么另开一个数组,储存序列排序,用于二分。

    那么对于每个二分的数,那么我们怎么来判断呢?

    对于每个数字x,我们对于每个判断序列中有多少个比x大的数和比x小的数,为了方便判断,预处理一个数组C,原序列中的数大于等于x,C[i]=1,否则C[i]=-1;

    我们判断这个数是不是中位数,那么就要让小于它的数和大于等于它的数数量相等。

    循环判断,当现枚举的长度大于等于想要的长度时,找出左边最少有多少个比它小的数,往右找到比它大的数。

    if(i>=len)ban=min(ban,c[i-len]);

    我们每次前缀和,统计+1和-1的数量差。

    c[i]+=c[i-1];

    满足条件go on!!

    if(i>=len&&c[i]-ban>0)return 1;

    总的时间复杂度$O(nlongn)$

    代码:

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    #define LL long long
    int read()
    {
        int sum=0,fg=1; char c=getchar();
        while(c<'0'||c>'9'){ if(c=='-')fg=-1;c=getchar(); }
        while(c>='0'&&c<='9'){ sum=sum*10+c-'0';c=getchar(); }
        return sum*fg;
    }
    int n,len,a[100006],b[100006];
    int c[100006],ban,ans;
    bool check(int x)
    {
        ban=1234567890;
        for(int i=1;i<=n;i++)
            if(a[i]>=x)c[i]=1; else c[i]=-1;
        bool flag=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]==x)flag=1;
            if(i>=len)ban=min(ban,c[i-len]);
            c[i]+=c[i-1];
            if(i>=len&&c[i]-ban>0)return 1;
        }
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&len);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+1+n);
        int l=n/2,r=n;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(check(b[mid]))ans=b[mid],l=mid+1;
            else r=mid-1;
        }
        printf("%d",ans);
    }
  • 相关阅读:
    Nutch的配置(使用MySQL作为数据存储)
    MySQL简单实现多字段模糊查询
    nutch的一些基础整理
    Java分布式爬虫Nutch教程——导入Nutch工程,执行完整爬取
    Nutch2 WebPage写入数据库的过程分析
    Nutch2 WebPage 字段解释
    nutch如何修改regex-urlfilter.txt爬取符合条件的链接
    Run Nutch In Eclipse on Linux and Windows nutch version 0.9
    Linux Mint 17.1 安装全配置
    Ubuntu(Linux Mint):sudo apt-get upgrade升级失败
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9614724.html
Copyright © 2011-2022 走看看