• HDU 2852 KiKi's K-Number (树状数组 && 二分)


    题意 : 给出对容器的总操作次数n, 接下来是这n个操作。这里对于一个容器提供三种操作, 分别是插入、删除和查找。输入0  e表示插入e、输入1  e表示删除e,若元素不存在输出No Elment!、输入2  e  k表示查找比e大且第k大的数, 若不存在则输出Not Find!

    分析 : 这里考虑树状数组做的原因是在第三个操作的时候, 只要我们记录了元素的总数, 那通过求和操作, 便能够高效地知道到底有多少个数比现在求和的这个数要大, 例如 tot - sum(3)就能知道整个集合里面比3大的数到底有多少个(tot代表集合里面元素的总数)。如果大于或等于 k 则存在比这个数大且是第k大的数, 接下来只要二分查找即可!

    瞎搞 : 当时没有想到二分, 而是直接丢进一个multiset中, 然后进行迭代查找操作, 别说了, TEL得好惨……

    #include<bits/stdc++.h>
    #define lowbit(i) (i&(-i))
    using namespace std;
    const int maxn = 1e5+1;
    int c[maxn];
    inline void add(int i, int val)
    {
        while(i<=100000){
            c[i] += val;
            i += lowbit(i);
        }
    }
    int sum(int i)
    {
        int ans = 0;
        while(i>0){
            ans += c[i];
            i -= lowbit(i);
        }
        return ans;
    }
    int vis[maxn];
    int Bin_search(int L, int R, int key, int index)
    {
        int mid;
        while(L < R){
            mid = L + ((R-L)>>1);
            if(sum(mid) - sum(index)  < key) L = mid + 1;
            else R = mid;
        }
        return R;
    }
    int main(void)
    {
        int n;
        while(~scanf("%d", &n) && n){
            memset(c, 0, sizeof(c));
            memset(vis, 0, sizeof(vis));
            int command;
            int tot = 0;
            int M = 0;
            for(int t=1; t<=n; t++){
                scanf("%d", &command);
                if(command==0){
                    int temp;
                    scanf("%d", &temp);
                    if(temp>M) M = temp;
                    vis[temp]++;
                    add(temp, 1);
                    tot++;
                }
                else if(command==1){
                    int temp;
                    scanf("%d", &temp);
                    if(vis[temp]){
                        tot--;
                        add(temp, -1);
                        vis[temp]--;
                    }else{
                        puts("No Elment!");
                    }
                }
                else{
                    int a, b;
                    int ans;
                    scanf("%d%d", &a, &b);
                    if(tot-sum(a) >= b){
                        int ans = Bin_search(a, M, b, a);
                        printf("%d
    ", ans);
                    }else{
                        puts("Not Find!");
                    }
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    zabbix (2.0.6) 历史记录处乱码
    centos 关闭防火墙
    android 带边框的圆角按钮
    Android开发如何在4.0及以上系统中自定义TitleBar
    Android配置时,点击eclipse里Window->Preferences里的android选项出错
    .net 内存泄露检测工具
    UVA 548 Tree
    UVA 536 Tree Recovery
    UVA 514 Rails
    UVA 442 Matrix Chain Multiplication
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/6917081.html
Copyright © 2020-2023  润新知