玄学调过,蒟蒻不理解
查看原帖
玄学调过,蒟蒻不理解
832472
yishanyi楼主2024/12/25 21:01

用线段树套TreapTreap(权值线段树版)做的这题(轻喷),但在操作一的时候为什么不能直接查kk的排名,还必须写成qry_rank(1, 1, n, l, r, k - 1) + 1才能过呢?

相关代码(应该只有这些吧):

struct Treap_Node {

    int l_son, r_son, cnt, Max, Min;

} t[M];

struct Treap {

#define ls t[u].l_son
#define rs t[u].r_son
#define mid ((l + r) >> 1)

    static inline void get_new(int& u) { t[(u = ++idx)] = {0, 0, 0, INT_MIN, INT_MAX}; }

    static inline void up(const int& u) {
        t[u].cnt = t[ls].cnt + t[rs].cnt;
        t[u].Max = max(t[ls].Max, t[rs].Max);
        t[u].Min = min(t[ls].Min, t[rs].Min);
    }

    inline void insert(int& u, const int& l, const int& r, const int& x) {

        if (!u) get_new(u);
        if (l == r) { t[u].cnt++, t[u].Max = t[u].Min = l; return; }
        if (x <= mid) insert(ls, l, mid, x);
        else insert(rs, mid + 1, r, x);
        up(u);

    }

    inline void erase(int& u, const int& l, const int& r, const int& x) {

        if (!u) get_new(u);
        if (l == r) {
            t[u].cnt = max(0, t[u].cnt - 1);
            if (!t[u].cnt) t[u].Max = INT_MIN, t[u].Min = INT_MAX;
            return;
        }
        if (x <= mid) erase(ls, l, mid, x);
        else erase(rs, mid + 1, r, x);
        up(u);

    }

    inline int qry_rank(const int& u, const int& l, const int& r, const int& x) {

        if (!u) return 0;
        if (l > x) return 0;
        if (r <= x) return t[u].cnt;
        return qry_rank(ls, l, mid, x) + qry_rank(rs, mid + 1, r, x);

    }

#undef ls
#undef rs
#undef mid

};

struct Seg_Tree {

    struct {

        int root;
        Treap set;

    } t[N << 2];

#define ls (u << 1)
#define rs (u << 1 | 1)
#define mid ((l + r) >> 1)
#define set t[u].set
#define root t[u].root

    inline void blt(const int& u, const int& l, const int& r) {

        for (int i = l; i <= r; i++) set.insert(root, L, R, a[i]);
        if (l == r) return;
        blt(ls, l, mid), blt(rs, mid + 1, r);

    }

    inline void cgt(const int& u, const int& l, const int& r, const int& k, const int& x) {

        set.erase(root, L, R, a[k]);
        set.insert(root, L, R, x);
        if (l == r) return;
        if (k <= mid) cgt(ls, l, mid, k, x);
        else cgt(rs, mid + 1, r, k, x);

    }

    inline int qry_rank(const int& u, const int& l, const int& r, const int& ql, const int& qr, const int& x) {

        if (l > qr || r < ql) return 0;
        if (l >= ql && r <= qr) return set.qry_rank(root, L, R, x);
        return qry_rank(ls, l, mid, ql, qr, x) + qry_rank(rs, mid + 1, r, ql, qr, x);

    }

#undef ls
#undef rs
#undef mid
#undef set
#undef root

} T;

这样的话操作一的询问必须写成T.qry_rank(1, 1, n, l, r, k - 1) + 1才对,不能直接写T.qry_rank(1, 1, n, l, r, k)

求大佬答疑

2024/12/25 21:01
加载中...