【数据结构】线段树(名次树)

struct SegmentTree {
#define ls (o<<1)
#define rs (o<<1|1)
    static const int MAXN = 100000;
    int cnt[(MAXN << 2) + 5];

    void PushUp(int o) {
        cnt[o] = cnt[ls] + cnt[rs];
    }

    void Build(int o, int l, int r) {
        if(l == r)
            cnt[o] = 0;
        else {
            int m = l + r >> 1;
            Build(ls, l, m);
            Build(rs, m + 1, r);
            PushUp(o);
        }
    }

    //修改值为p的元素的个数,增量为v,且不能为负
    void Update(int o, int l, int r, int p, int v) {
        if(l == r) {
            cnt[o] += v;
            if(cnt[o] < 0)
                cnt[o] = 0;
            return;
        } else {
            int m = l + r >> 1;
            if(p <= m)
                Update(ls, l, m, p, v);
            if(p >= m + 1)
                Update(rs, m + 1, r, p, v);
            PushUp(o);
        }
    }

    //查询<=x的元素的个数
    int GetRank(int o, int l, int r, int x) {
        if(r <= x) {
            return cnt[o];
        } else {
            int m = l + r >> 1;
            if(x <= m)
                return GetRank(ls, l, m, x);
            else
                return cnt[ls] + GetRank(rs, m + 1, r, x);
        }
    }

    //查询最小的x,使得<=x的元素个数>=rk
    int GetValue(int o, int l, int r, int rk) {
        if(l == r) {
            return l;
        } else {
            int m = l + r >> 1;
            if(cnt[ls] >= rk)
                return GetValue(ls, l, m, rk);
            else
                return GetValue(rs, m + 1, r, rk - cnt[ls]);
        }
    }
#undef ls
#undef rs
} st;
posted @ 2021-01-12 01:21  purinliang  阅读(67)  评论(0编辑  收藏  举报