洛谷P2617 Dynamic Rankings 题解 树套树(树状数组 套 权值线段树)

题目链接:https://www.luogu.com.cn/problem/P2617

这题应该算模板题吧。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5, inf = 1e9;

int n, m, a[maxn];

struct SegmentTree {

    int tr[maxn*300], ls[maxn*300], rs[maxn*300], idx;

    void push_up(int u) {
        int l = ls[u], r = rs[u];
        tr[u] = tr[l] + tr[r];
    }

    void add(int p, int val, int l, int r, int &u) {
        if (!u) u = ++idx;
        if (l == r) {
            tr[u] += val;
            return;
        }
        int mid = l + r >> 1;
        (p <= mid) ? add(p, val, l, mid, ls[u]) : add(p, val, mid+1, r, rs[u]);
        push_up(u);
    }

    int query(int L, int R, int l, int r, int u) {
        if (!u) return 0;
        if (L <= l && r <= R) return tr[u];
        int res = 0, mid = l + r >> 1;
        if (L <= mid) res += query(L, R, l, mid, ls[u]);
        if (R > mid) res += query(L, R, mid+1, r, rs[u]);
        return res;
    }

    int kth(int l, int r, int k, vector<int> &t1, vector<int> &t2) {
        if (l == r) return l;
        int cnt = 0, mid = l + r >> 1;
        for (auto u : t1) {
            int l = ls[u];
            cnt += tr[l];
        }
        for (auto u : t2) {
            int l = ls[u];
            cnt -= tr[l];
        }
        if (cnt >= k) {
            for (auto &u : t1) u = ls[u];
            for (auto &u : t2) u = ls[u];
            return kth(l, mid, k, t1, t2);
        }
        else {
            for (auto &u : t1) u = rs[u];
            for (auto &u : t2) u = rs[u];
            return kth(mid+1, r, k - cnt, t1, t2);
        }
    }

} seg_t;

struct BIT {

    int tr[maxn];
    int lowbit(int x) { return x & -x; }

    void add(int p, int x, int val) {
        for (int i = p; i <= n; i += lowbit(i))
            seg_t.add(x, val, 0, inf, tr[i]);
    }

    void get_tr(int p, vector<int> &vec) {
        for (int i = p; i; i -= lowbit(i))
            vec.push_back(tr[i]);
    }

    int kth(int l, int r, int k) {
        vector<int> t1, t2;
        get_tr(r, t1);
        get_tr(l-1, t2);
//        cout << "t1: "; for (auto u : t1) cout << u << ", "; cout << endl;
//        cout << "t2: "; for (auto u : t2) cout << u << ", "; cout << endl;
        int res = seg_t.kth(0, inf, k, t1, t2);
        return res;
    }

} bit;

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", a+i);
        bit.add(i, a[i], 1);
    }
    while (m--) {
        char op[2];
        scanf("%s", op);
        if (op[0] == 'C') { // C x y
            int x, y;
            scanf("%d%d", &x, &y);
            bit.add(x, a[x], -1);
            a[x] = y;
            bit.add(x, a[x], 1);
        }
        else {  // Q l r k
            int l, r, k;
            scanf("%d%d%d", &l, &r, &k);
            int ans = bit.kth(l, r, k);
            printf("%d\n", ans);
        }
    }
    return 0;
}
posted @ 2026-01-08 19:30  quanjun  阅读(1)  评论(0)    收藏  举报