AcWing2488. 树套树-简单版 题解 树套树(线段树 套 STL(multiset))

题目链接:https://www.acwing.com/problem/content/description/2490/

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 5;

multiset<int> tr[maxn<<2];
int n, q, a[maxn];

void build(int l, int r, int u) {
    for (int i = l; i <= r; i++)
        tr[u].insert(a[i]);
    if (l == r) return;
    int mid = l + r >> 1;
    build(l, mid, u<<1);
    build(mid+1, r, u<<1|1);
}

void change(int p, int x, int l, int r, int u) {
    tr[u].erase(tr[u].find(a[p]));
    tr[u].insert(x);
    if (l == r) return;
    int mid = l + r >> 1;
    (p <= mid) ? change(p, x, l, mid, u<<1) : change(p, x, mid+1, r, u<<1|1);
}

int query(int L, int R, int x, int l, int r, int u) {
    if (L <= l && r <= R) {
        auto it = tr[u].lower_bound(x);
        if (it == tr[u].begin())
            return -1;
        else {
            it--;
            return *it;
        }
    }
    int res = -1, mid = l + r >> 1;
    if (L <= mid) res = max(res, query(L, R, x, l, mid, u<<1));
    if (R > mid) res = max(res, query(L, R, x, mid+1, r, u<<1|1));
    return res;
}

int main() {
    scanf("%d%d", &n, &q);
    for (int i = 1; i <= n; i++)
        scanf("%d", a+i);
    build(1, n, 1);
    for (int i = 0, op; i < q; i++) {
        scanf("%d", &op);
        if (op == 1) {
            int p, x;
            scanf("%d%d", &p, &x);
            change(p, x, 1, n, 1);
            a[p] = x;
        }
        else {
            int l, r, x;
            scanf("%d%d%d", &l, &r, &x);
            int ans = query(l, r, x, 1, n, 1);
            printf("%d\n", ans);
        }
    }
    return 0;
}
posted @ 2025-12-25 03:09  quanjun  阅读(3)  评论(0)    收藏  举报