zoukankan      html  css  js  c++  java
  • hdu 2852 KiKi's K-Number

    题意:

    最开始有一个空的数组,有3中操作:

    1.插入一个元素

    2.删除一个元素

    3.查询比a大的第k个元素是多少。

    思路:

    主要是第三个操作

    树状数组求第k大是用的二分,判断满足的条件是大于等于0

    这题首先得求出小于等于a的元素,假设是cnt,那么大于它的第k个元素,求的就是整个数组的第cnt + k小元素,直接二分就行了。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int N = 1e5 + 10;
     6 int c[N];
     7 int vis[N];
     8 int lowbit(int x)
     9 {
    10     return x&(-x);
    11 }
    12 void add(int x,int y)
    13 {
    14     for (int i = x;i <= N - 5;i += lowbit(i)) c[i] += y;
    15 }
    16 int getsum(int x)
    17 {
    18     int ans = 0;
    19     for (int i = x;i > 0;i -= lowbit(i)) ans += c[i];
    20     return ans;
    21 }
    22 int main()
    23 {
    24     int m;
    25     while (scanf("%d",&m) != EOF)
    26     {
    27         memset(c,0,sizeof(c));
    28         memset(vis,0,sizeof(vis));
    29         int cnt = 0;
    30         while (m--)
    31         {
    32             int op;
    33             scanf("%d",&op);
    34             if (op == 0)
    35             {
    36                 int e;
    37                 scanf("%d",&e);
    38                 vis[e]++;
    39                 add(e,1);
    40                 cnt++;
    41             }
    42             if (op == 1)
    43             {
    44                 int e;
    45                 scanf("%d",&e);
    46                 if (vis[e] <= 0)
    47                 {
    48                     puts("No Elment!");
    49                 }
    50                 else
    51                 {
    52                     add(e,-1);
    53                     vis[e]--;
    54                     cnt--;
    55                 }
    56             }
    57             if (op == 2)
    58             {
    59                 int a,k;
    60                 scanf("%d%d",&a,&k);
    61                 int tmp = getsum(a);
    62                 if (tmp + k > cnt)
    63                 {
    64                     puts("Not Find!");
    65                 }
    66                 else
    67                 {
    68                     int l = 1,r = N;
    69                     while (r - l > 1)
    70                     {
    71                         int mid = (l + r) >> 1;
    72                         if (getsum(mid) >= tmp + k) r = mid;
    73                         else l = mid + 1;
    74                     }
    75                     while (getsum(r-1) >= tmp + k) r--;
    76                     printf("%d
    ",r);
    77                 }
    78             }
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    0523
    [算法]二分专题
    [转]聊聊列式存储
    [错误]Caused by: org.apache.spark.memory.SparkOutOfMemoryError: Unable to acquire 65536 bytes of memory, got 0
    [转]为什么group by后面不能使用别名(除MySQL)
    [算法]PriorityQueue的应用
    双指针算法
    [算法]实现strStr()
    实现用SQL查询连续发文天数/连续登录天数
    python 日志模块
  • 原文地址:https://www.cnblogs.com/kickit/p/9080883.html
Copyright © 2011-2022 走看看