Cod sursa(job #2645931)

Utilizator ursu2001Ursu Ianis-Vlad ursu2001 Data 30 august 2020 10:31:19
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.44 kb
#include <bits/stdc++.h>

using namespace std;

struct Node
{
    uint_fast32_t maximum;


    void set(uint_fast32_t value)
    {
        this->maximum = value;
    }


    void update(Node& l_child, Node& r_child)
    {
        this->maximum = max(l_child.maximum, r_child.maximum);
    }
};


class SegmentTree
{
    uint_fast32_t size;

    vector<Node> segment_tree;

    void build(vector<uint_fast32_t>& data, uint_fast32_t left, uint_fast32_t right, uint_fast32_t node_id)
    {
        if(left == right)
        {
            segment_tree[node_id].set(data[left]);
            return;
        }

        uint_fast32_t l_child_id = 2 * node_id;
        uint_fast32_t r_child_id = 2 * node_id + 1;
        uint_fast32_t middle = (left + right) / 2;

        build(data, left, middle, l_child_id);
        build(data, middle + 1, right, r_child_id);

        segment_tree[node_id].update(segment_tree[l_child_id], segment_tree[r_child_id]);
    }


    void __update(uint_fast32_t index, uint_fast32_t value, uint_fast32_t left, uint_fast32_t right, uint_fast32_t node_id)
    {
        if(left == right)
        {
            segment_tree[node_id].set(value);
            return;
        }

        uint_fast32_t l_child_id = 2 * node_id;
        uint_fast32_t r_child_id = 2 * node_id + 1;
        uint_fast32_t middle = (left + right) / 2;

        if(index <= middle)
        {
            __update(index, value, left, middle, l_child_id);
        }
        else
        {
            __update(index, value, middle + 1, right, r_child_id);
        }

        segment_tree[node_id].update(segment_tree[l_child_id], segment_tree[r_child_id]);
    }


    uint_fast32_t __query(uint_fast32_t a, uint_fast32_t b, uint_fast32_t left, uint_fast32_t right, uint_fast32_t node_id)
    {
        if(a <= left && right <= b)
        {
            return segment_tree[node_id].maximum;
        }

        uint_fast32_t l_child_id = 2 * node_id;
        uint_fast32_t r_child_id = 2 * node_id + 1;
        uint_fast32_t middle = (left + right) / 2;

        uint_fast32_t answer = 0;

        if(a <= middle)
        {
            answer = __query(a, b, left, middle, l_child_id);
        }

        if(b > middle)
        {
            answer = max(answer, __query(a, b, middle + 1, right, r_child_id));
        }

        return answer;
    }


public:
    SegmentTree(vector<uint_fast32_t>& data)
    {
        this->size = data.size() - 1;

        segment_tree.resize(4 * this->size + 5);

        build(data, 1, this->size, 1);
    }


    void update(uint_fast32_t index, uint_fast32_t value)
    {
        __update(index, value, 1, this->size, 1);
    }


    uint_fast32_t query(uint_fast32_t a, uint_fast32_t b)
    {
        return __query(a, b, 1, this->size, 1);
    }

};



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

    uint_fast32_t N, M;
    fin >> N >> M;

    vector<uint_fast32_t> data(N + 1);

    for(uint_fast32_t i = 1; i <= N; ++i)
    {
        fin >> data[i];
    }

    SegmentTree segment_tree(data);


     for(uint_fast32_t i = 1; i <= M; ++i)
     {
         uint_fast32_t type, a, b;
         fin >> type >> a >> b;

         if(type == 1)
         {
             segment_tree.update(a, b);
         }
         else
         {
             fout << segment_tree.query(a, b) << '\n';
         }
     }
}