#include <iostream>
#include <queue>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;
int n, m;
const int N = 50010, M = N * 4, INF = 1e9;
struct Tree {
int l, r;
multiset<int>s;
} tr[M];
int w[N];
void build(int u, int l, int r) {
tr[u] = {l, r};
tr[u].s.insert(-INF), tr[u].s.insert(INF);
for (int i = l; i <= r; i ++ ) tr[u].s.insert(w[i]);
if (l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}
void change(int u, int p, int x) {
tr[u].s.erase(tr[u].s.find(w[p]));//删掉原本的数
tr[u].s.insert(x);
if (tr[u].l == tr[u].r)
return ;
int mid = tr[u].l + tr[u].r >> 1;
if (p <= mid)
change(u << 1, p, x);
else
change(u << 1 | 1, p, x);
}
int query(int u, int a, int b, int x) {
if (tr[u].l >= a && tr[u].r <= b) {
auto it = tr[u].s.lower_bound(x);
--it;//找到小于x的最大数
return *it;
}
int mid = tr[u].l + tr[u].r >> 1, res = -INF;
if (a <= mid)
res = max(res, query(u << 1, a, b, x));
if (b > mid)
res = max(res, query(u << 1 | 1, a, b, x));
return res;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> w[i];
build(1, 1, n);
while (m--) {
int op, a, b, x;
cin >> op;
if (op == 1) {
cin >> a >> x;
change(1, a, x);
w[a] = x;
} else {
cin >> a >> b >> x;
cout << query(1, a, b, x) << endl;
}
}
}
数据结构 树套树 线段树套set
最新推荐文章于 2022-04-04 11:51:32 发布