Pagini recente » Cod sursa (job #3140575) | Cod sursa (job #588669) | Borderou de evaluare (job #2030128) | Borderou de evaluare (job #1186253) | Cod sursa (job #3152422)
#include <bits/stdc++.h>
using namespace std;
#ifdef ONLINE_JUDGE
std::istream &in = std::cin;
std::ostream &out = std::cout;
#else
// std::ifstream in("input.txt");
// std::ostream &out = std::cerr;
#endif
std::ifstream in("arbint.in");
std::ofstream out("arbint.out");
// online/dynamic rmq using segment tree
struct SegTreeState {
// 4h minus 7
int n, h;
vector<int> segtree;
SegTreeState(int n) : n(n) {
h = countr_zero(bit_ceil(static_cast<unsigned>(n))) + 1;
segtree.resize(1 << h, numeric_limits<int>::max());
}
void update_point(int i, int x);
int range_min(int l, int r);
static inline constexpr int up(int node) {
return (node - 1) / 2;
}
static inline constexpr int down(int node) {
return node * 2 + 1;
}
// the leaves are the last elements of the array
inline constexpr int idx_from_arr_idx(int i) {
return i + (1 << (h - 1)) - 1;
}
};
void SegTreeState::update_point(int i, int x) {
i = idx_from_arr_idx(i);
segtree[i] = x;
// levels start on odd numbers, left is odd
int j = i - static_cast<int>(i % 2 == 0);
for (i = up(i); i != -1; i = up(i) - static_cast<int>(i == 0)) {
segtree[i] = max(segtree[j], segtree[j + 1]);
j = i - static_cast<int>(i % 2 == 0);
}
}
struct NodeData {
pair<int, int> target;
pair<int, int> limit;
int idx;
};
inline constexpr bool included_in_2(pair<int, int> p1, pair<int, int> p2) {
return p2.first <= p1.first && p2.second >= p1.second;
}
int SegTreeState::range_min(int l, int r) {
queue<NodeData> nodes;
nodes.push({.target = {l, r}, .limit = {0, (1 << (h - 1)) - 1}, .idx = 0});
int res = numeric_limits<int>::max();
while (!nodes.empty()) {
NodeData u = nodes.front();
nodes.pop();
if (included_in_2(u.limit, u.target)) {
res = max(res, segtree[u.idx]);
continue;
}
int m = midpoint(u.limit.first, u.limit.second);
// left
if (u.target.first <= m) {
nodes.push({
.target = {u.target.first, u.target.second},
.limit = {u.limit.first, m},
.idx = down(u.idx)});
}
// right
if (u.target.second > m) {
nodes.push({
.target = {u.target.first, u.target.second},
.limit = {m + 1, u.limit.second},
.idx = down(u.idx) + 1});
}
}
return res;
}
enum class Q { Update = 1, RangeMin = 0 };
int main() {
int n, q;
in >> n >> q;
SegTreeState s(n);
for (int i = 0; i < n; ++i) {
int x;
in >> x;
s.update_point(i, x);
}
for (int i = 0; i < q; ++i) {
Q query;
int a, b;
in >> reinterpret_cast<underlying_type_t<Q> &>(query) >> a >> b;
switch (query) {
case Q::Update: {
s.update_point(a - 1, b);
break;
}
case Q::RangeMin: {
out << s.range_min(a - 1, b - 1) << "\n";
break;
}
default:
assert(false);
}
}
}