训练日记-15

来源:互联网 发布:为知笔记 看别人的笔记 编辑:程序博客网 时间:2024/06/09 20:52

        这几天主要还是在看树状数组方面的知识点例题以及刷练习题,树状数组除了用于求和外,还可以用于找出容器中大于某个数的第k个数,还可以进行插入删除等操作,并且树状数组还可以用二分优化。其用二分优化的查找大于某个数的第k个数的基本模版如下:

#include <iostream>

using namespace std;

#define maxn 100002

int C[maxn], n;

int lowbit(int x) {

    return x & (-x);

}

void Add(int pos, int val) {

    while(pos < maxn) {

        C[pos] += val;

        pos += lowbit(pos);

    }

}

int Sum(int pos) {

    int S = 0;

    while(pos >= 1) {

        S += C[pos];

        pos -= lowbit(pos);

    }

    return S;

}

 

int find(int a, int k) {

    int l = a + 1;

    int r = maxn - 1;

    int S = Sum(a);

    int ans = maxn;

    while(l <= r) {

        int m = (l + r) >> 1;

        int nS = Sum(m);

        if(nS - S >= k) {

            r = m - 1;

            if(m < ans)

                ans = m;

        }else

            l = m + 1;

    }

    return ans;

}

 

int main() {

    int n;

    int i;

    while(scanf("%d", &n) != EOF) {

        for(i = 1; i < maxn; i++)

            C[i] = 0;

        while(n--) {

            int id, e, a, k;

            scanf("%d", &id);

            if(id == 0) {

                scanf("%d", &e);

                Add(e, 1);

            }else if(id == 1) {

                scanf("%d", &e);

                if(Sum(e) - Sum(e-1) == 0)

                    printf("No Elment!\n");

                else

                    Add(e, -1);

            }else {

                scanf("%d %d", &a, &k);

                int num = find(a, k);

                if(num == maxn) {

                    printf("Not Find!\n");

                }else

                    printf("%d\n", num);

            }

        }

    }

    return 0;

}


      其次今天下午的比赛只做出了b题的最短路径问题跟f题的贪心问题,可能是因为最近刚练习完这个专题b题做起来还是比较顺手的,但是a题不知道为什么就是过不了,结果对,但是一直超时,很郁闷。后面的那几道题实在是没有什么思路,毕竟也是一个人做的,能力也有限。

      继续加油!



原创粉丝点击