Pagini recente » Cod sursa (job #1248183) | Cod sursa (job #160736) | Cod sursa (job #1013399) | Cod sursa (job #1609431) | Cod sursa (job #1481889)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <cassert>
template<class Function>
class SegmentTree {
// CLASS FUNCTIONS
static std::size_t larger2Pow(std::size_t size) {
auto ret = 1ul;
while (ret < size)
ret *= 2ul;
return ret;
}
// DATA
Function d_folder;
std::size_t d_leaves;
std::vector<int> d_data;
public:
///
// Constructs a new segment tree from the given 'values' and the manipulator
// 'folder'.
///
template<class Lambda>
SegmentTree(const std::vector<int>& values, Lambda&& folder)
: d_folder(std::forward<Lambda>(folder))
, d_leaves{larger2Pow(values.size())}
, d_data(d_leaves * 2)
{
for (auto i = 0ul; i < values.size(); ++i)
d_data[d_leaves + i] = values[i];
for (auto i = values.size(); i < d_leaves; ++i)
d_data[d_leaves + i] = 0;
for (auto i = d_leaves - 1; i > 0ul; --i)
d_data[i] = d_folder(d_data[i * 2], d_data[i * 2 + 1]);
}
///
// Updates the value on position 'index'.
///
void update(int index, int value) {
index += d_leaves;
d_data[index] = value;
for (index /= 2; index > 0; index /= 2)
d_data[index] = d_folder(d_data[index * 2], d_data[index * 2 + 1]);
}
///
// Makes a query on the given interval [from, to], using the manipulator
// with which this segment tree has been constructed.
///
int query(int from, int to) {
auto ret = 0;
from += d_leaves;
to += d_leaves;
while (from <= to) {
ret = d_folder(ret, d_data[from]);
from = (from + 1) / 2;
ret = d_folder(ret, d_data[to]);
to = (to - 1) / 2;
}
return ret;
}
};
int main() {
std::ios_base::sync_with_stdio(false);
std::ifstream inStream{"arbint.in"};
std::ofstream outStream{"arbint.out"};
int N, M;
inStream >> N >> M;
auto values = std::vector<int>(N);
for (auto &value : values)
inStream >> value;
auto max = [](int lhs, int rhs) { return std::max(lhs, rhs); };
SegmentTree<decltype(max)> segTree{values, max};
for (auto i = 0; i < M; ++i) {
int type, x, y;
inStream >> type >> x >> y;
if (!type)
outStream << segTree.query(x - 1, y - 1) << "\n";
else
segTree.update(x - 1, y);
}
outStream << std::flush;
}