Cod sursa(job #2329543)

Utilizator igsifvevc avb igsi Data 26 ianuarie 2019 21:54:17
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 kb
#include <algorithm>
#include <fstream>
#include <iterator>
#include <limits>
#include <vector>

constexpr int MAX_TREE_SIZE = (1 << 18) - 1;

class Tree
{
    std::vector<int> tree;
    int n_elements;

  public:
    Tree(const std::vector<int> &v)
        : tree(MAX_TREE_SIZE, 0), n_elements(v.size())
    {
        for (int i = 0; i < this->n_elements; ++i)
        {
            this->insert(v[i], i);
        }
    }

    void insert(const int value, const int pos)
    {
        this->insert(value, pos, 0, 0, this->n_elements);
    }

    int max(const int l, const int r)
    {
        return this->max(l, r, 0, 0, this->n_elements);
    }

  private:
    void insert(const int x, const int pos, const int i, const int l, const int r)
    {
        if (r - l == 1)
        {
            tree[i] = x;
            return;
        }

        int middle = l + (r - l) / 2;

        if (pos < middle)
            this->insert(x, pos, 2 * i + 1, l, middle);
        else
            this->insert(x, pos, 2 * i + 2, middle, r);

        tree[i] = std::max(tree[2 * i + 1], tree[2 * i + 2]);
    }

    int max(const int a, const int b, const int i, const int l, const int r)
    {
        if (a <= l && r <= b)
        {
            return tree[i];
        }

        int middle = l + (r - l) / 2;
        int u, v;

        u = v = std::numeric_limits<int>::min();
        if (a < middle)
            u = this->max(a, b, 2 * i + 1, l, middle);
        if (middle < b)
            v = this->max(a, b, 2 * i + 2, middle, r);

        return std::max(u, v);
    }
};

int main()
{
    std::ifstream fin("arbint.in");
    std::ofstream fout("arbint.out");

    int n, m;
    fin >> n >> m;

    std::vector<int> v;
    std::copy_n(std::istream_iterator<int>(fin), n, std::back_inserter(v));

    Tree tree(v);

    int op, a, b;
    while (m--)
    {
        fin >> op >> a >> b;
        switch (op)
        {
        case 0:
            fout << tree.max(a - 1, b) << '\n';
            break;
        case 1:
            tree.insert(b, a - 1);
            break;
        }
    }

    return 0;
}