• 2017.10.7 国庆清北 D7T2 第k大区间


    题目描述

    定义一个长度为奇数的区间的值为其所包含的的元素的中位数。

    现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少。

    输入输出格式

    输入格式:

    输入文件名为kth.in。

    第一行两个数n和k

    第二行,n个数。(0<=每个数<2^31)

    输出格式:

    一个数表示答案

    输入输出样例

    输入样例#1:
    4 3
    3 1 2 4	
    
    【样例解释】
    [l,r]表示区间l~r的值
    [1,1]:3
    [2,2]:1
    [3,3]:2
    [4,4]:4
    [1,3]:2
    [2,4]:2
    输出样例#1:
    2

    说明

    对于30%的数据,1<=n<=100;

    对于60%的数据,1<=n<=300

    对于80%的数据,1<=n<=1000

    对于100%的数据,1<=n<=100000, k<=奇数区间的数

     1 /*
     2 二分答案t,统计中位数大于等于t的区间有多少个。
     3 设a[i]为前i个数中有a[i]个数>=t,若奇数区间[l,r]的中位数>=t,则(a[r]-a[l-1])*2>r-l+1,即(a[r]*2-r)>(a[l-1]*2-l+1)。
     4 设b[i]=a[i]*2-i,统计每个b[i]有多少个b[j]<b[i](j<i 且 j和i奇偶性不同)
     5 */
     6 
     7 #include<iostream>
     8 #include<cstdio>
     9 #include<cstring>
    10 #include<algorithm>
    11 #include<cmath>
    12 #define N 100005
    13 using namespace std;
    14 
    15 long long n,k,ans;
    16 int a[N],b[N],c[N],f[2][N*3];
    17 
    18 inline int lowbit(int x)
    19 {
    20     return x&-x;
    21 }
    22 
    23 inline void add(int x,int p)
    24 {
    25     if(x<=0) return;
    26     for(;x<=3*n;x+=lowbit(x)) f[p][x]++;
    27 }
    28 
    29 inline int query(int x,int p)
    30 {
    31     if(x<=0) return 0;
    32     int sum=0;
    33     for(;x;x-=lowbit(x)) sum+=f[p][x];
    34     return sum;
    35 }
    36 
    37 long long check(int x)
    38 {
    39     memset(f,0,sizeof(f));
    40     long long sum=0;
    41     for(int i=1;i<=n;i++)
    42     {
    43         c[i]=c[i-1]+(a[i]>=x);
    44     }
    45     for(int i=1;i<=n;i++)
    46     {        
    47         c[i]=c[i]*2-i+n;
    48     }
    49     add(n,0);
    50     for(int i=1;i<=n;i++)
    51     {
    52         add(c[i],i&1);
    53         sum+=query(c[i]-1,(i+1)&1);
    54     }
    55     return sum;
    56 }
    57 
    58 inline void init()
    59 {
    60     scanf("%lld%lld",&n,&k);
    61     for(int i=1;i<=n;i++)
    62     {
    63         scanf("%d",&a[i]);
    64         b[i]=a[i];
    65     }
    66     sort(b+1,b+n+1);
    67     int l=1,r=n+1,mid=(l+r)>>1;
    68     while(l+1<r)
    69     {
    70         if(check(b[mid])>=k) l=mid;
    71         else r=mid;
    72         mid=(l+r)>>1;
    73     }
    74     printf("%d",b[l]);
    75 }
    76 
    77 int main()
    78 {
    79     init();
    80     fclose(stdin);fclose(stdout);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    小白专场-堆中的路径-python语言实现
    小白专场-堆中的路径-c语言实现
    集合及运算
    哈弗曼树与哈夫曼编码

    线性结构之习题选讲-ReversingLinkedList
    小白专场-是否同一颗二叉搜索树-python语言实现
    微信公众平台开发教程第1篇-新手解惑(转)
    GIT GUI的使用(转)
    Git操作指南(2) —— Git Gui for Windows的建库、克隆(clone)、上传(push)、下载(pull)、合并(转)
  • 原文地址:https://www.cnblogs.com/lovewhy/p/7651820.html
Copyright © 2020-2023  润新知