Pagini recente » Cod sursa (job #892364) | Cod sursa (job #2035278) | Rating Lemnariu Dan (Lemnariu) | Cod sursa (job #1614746) | Cod sursa (job #1764876)
#include <fstream>
#include <vector>
#include <algorithm>
#include <utility>
#include <memory>
#include <iterator>
namespace cpp14
{
template <class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args) {return std::unique_ptr<T>(new T(std::forward<Args>(args)...));}
};
struct file_manip {
std::ifstream fin;
std::ofstream fout;
file_manip(const char* filename) {
std::string infilename = std::string(filename) + ".in";
std::string outfilename = std::string(filename) + ".out";
fin.open(infilename.c_str());
fout.open(outfilename.c_str());
}
template <class T>
file_manip& operator << (const T& rhs) {
fout << rhs;
return *this;
}
template <class T>
file_manip& operator >> (T& rhs) {
fin >> rhs;
return *this;
}
template <class T>
std::ostream_iterator<T> GetOstreamIterator() {
return std::ostream_iterator<T>(fout);
}
template <class T>
std::istream_iterator<T> GetIstreamIterator() {
return std::istream_iterator<T>(fin);
}
template <class T>
std::vector<T> ReadVector(int size)
{
std::vector<T> v;
v.reserve(size);
std::copy_n(GetIstreamIterator<int>(), size, std::back_inserter(v));
return v;
}
};
struct Arbint
{
std::unique_ptr<Arbint> left_child, right_child;
unsigned int value : 30;
int left : 17;
int right : 17;
Arbint(int left, int right, const std::vector<unsigned int>& vals) : left(left), right(right)
{
if (left == right)
{
value = vals[left];
}
else
{
auto middle = (left + right) / 2;
left_child = cpp14::make_unique<Arbint>(left, middle, vals);
right_child = cpp14::make_unique<Arbint>(middle + 1, right, vals);
value = std::max(left_child->value, right_child->value);
}
}
Arbint(const std::vector<unsigned int>& vals)
: Arbint(0, vals.size() - 1, vals) {}
void Update(unsigned int newVal, int pos)
{
if (left == right)
{
value = newVal;
}
else
{
const auto middle = (left + right) / 2;
if (pos <= middle)
{
left_child->Update(newVal, pos);
}
else
{
right_child->Update(newVal, pos);
}
value = std::max(left_child->value, right_child->value);
}
}
unsigned int GetValue(int a, int b) const
{
if (left >= a && right <= b)
return value;
const auto middle = (left + right) / 2;
auto v1 = 0u;
auto v2 = 0u;
if (middle >= a)
{
v1 = left_child->GetValue(a, b);
}
if (middle < b)
{
v2 = right_child->GetValue(a, b);
}
return std::max(v1, v2);
}
};
int main(int argc, char const *argv[])
{
file_manip fm("arbint");
int N, M;
int op;
unsigned int a, b;
fm >> N >> M;
Arbint arb(fm.ReadVector<unsigned int>(N));
while (M--)
{
fm >> op >> a >> b;
if (op == 0)
{
fm << arb.GetValue(a - 1, b - 1) << "\n";
}
else
{
arb.Update(b, a - 1);
}
}
return 0;
}