用线段树套Treap(权值线段树版)做的这题(轻喷),但在操作一的时候为什么不能直接查k的排名,还必须写成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)
求大佬答疑