• 51nod1685 第K大区间2


    Description

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

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

    样例解释:


    [l,r]表示区间的值
    [1]:3
    [2]:1
    [3]:2
    [4]:4
    [1,3]:2
    [2,4]:2


    第三大是2

    Input

    第一行两个数n和k(1<=n<=100000,k<=奇数区间的数量)
    第二行n个数,0<=每个数<2^31

    Output

    一个数表示答案。

    Input示例

    4 3
    3 1 2 4

    Output示例

    2

    解题思路:(二分+树状数组)

    区间第k大首先想到二分求中位数>=x的区间有多少个,所以快速求满足条件的区间才是关键,若大于等于x则1,否则 - 1;等到一个数组,求任意区间和>= 0 的奇数长度区间的个数即可,用两个数组数组分别维护区间和,在他前面和<=当前和的小标奇偶性不同的区间总个数,统计一下即可。

    Code

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define MAXN 100000 + 10
     4 #define INF (1<<30) - 1 + (1 << 30)
     5 int a[MAXN];
     6 int jtree[2 * MAXN];//奇数
     7 int otree[2 * MAXN];//偶数
     8 int lowbit(int x)
     9 {
    10     return x & (-x);
    11 }
    12 void jAdd(int k)
    13 {
    14     while(k < 2 *MAXN)
    15     {
    16         jtree[k] ++;
    17         k += lowbit(k);
    18     }
    19 }
    20 
    21 
    22 int jSum(int k)
    23 {
    24     int sum = 0;
    25     while(k)
    26     {
    27         sum += jtree[k];
    28         k -= lowbit(k);
    29     }
    30     return sum;
    31 }
    32 void oAdd(int k)
    33 {
    34     while(k < 2 *MAXN)
    35     {
    36         otree[k] ++;
    37         k += lowbit(k);
    38     }
    39 }
    40 
    41 
    42 int oSum(int k)
    43 {
    44     int sum = 0;
    45     while(k)
    46     {
    47         sum += otree[k];
    48         k -= lowbit(k);
    49     }
    50     return sum;
    51 }
    52 int main()
    53 {
    54     int n;
    55     long long k;
    56     scanf("%d%lld",&n,&k);
    57     for(int i = 0; i < n; i++)
    58         scanf("%d",a+i);
    59     long long l = 0,r = INF,mid;
    60     while(l < r)
    61     {
    62         memset(jtree,0,sizeof(jtree));
    63         memset(otree,0,sizeof(otree));
    64            // jAdd(MAXN);
    65         mid = (r + l + 1) / 2;
    66        // printf("%d...
    ",mid);
    67         long long sum = 0,ans = 0;
    68         for(int i = 0; i < n; i ++)
    69         {
    70             if(a[i] >= mid)
    71             {
    72                 sum ++;
    73             }
    74             else
    75                 sum--;
    76             if(i % 2 == 0)
    77             {
    78                 ans += jSum(sum + MAXN -1);
    79                 oAdd(sum + MAXN);
    80                 if(sum > 0)
    81                     ans ++;
    82             }
    83             else
    84             {
    85                 ans += oSum(sum + MAXN - 1);
    86                 jAdd(sum + MAXN);
    87             }
    88         }
    89         if(ans >= k)
    90             l = mid;
    91         else
    92             r = mid - 1;
    93     }
    94     printf("%lld
    ",l);
    95     return 0;
    96 }
  • 相关阅读:
    Linux PXE无人值守网络装机
    Linux 自动化部署DNS服务器
    Linux DNS服务配置
    Mysql数据库基础学习笔记
    Linux AIDE(文件完整性检测)
    mysql:[Err] 1068
    sql的date、时间函数、时间戳
    hive之建立分区表和分区
    excel转sql代码
    spark-submit之使用pyspark
  • 原文地址:https://www.cnblogs.com/yutingmoran/p/5901567.html
Copyright © 2020-2023  润新知