Cod sursa(job #3203170)

Utilizator MagicantPlusIuoras Andrei MagicantPlus Data 13 februarie 2024 10:42:56
Problema Arbori de intervale Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

ifstream fin("arbint.in");
ofstream fout("arbint.out");

#define cin fin
#define cout fout

struct segTree_
{
    vector<int> tree_;
    int elementsSize;

    segTree_();
    void resize(int n);
    void build(vector<int>& elements);
    void build_(vector<int>& elements, int node, int left, int right);
    void update(int index, int val);
    void update_(int index, int val, int node, int left, int right);
    int rangeQuery(int leftQ, int rightQ);
    int rangeQuery_(int leftQ, int rightQ, int node, int left, int right);
};

int main()
{
    int n, q;
    segTree_ segmentTree;
    vector<int> elements;

    cin >> n >> q;
    elements.resize(n);

    for(int i = 0; i < n; i++)
    {
        cin >> elements[i];
    }

    segmentTree.build(elements);

    for(int i = 0, queryType, a, b; i < q; i++)
    {
        cin >> queryType >> a >> b;

        if(queryType == 0)
        {
            a--;
            b--;
            cout << segmentTree.rangeQuery(a, b) << '\n';
        }
        else
        {
            a--;
            segmentTree.update(a, b);
        }
    }

    return 0;
}

segTree_::segTree_()
{

}
void segTree_::resize(int n)
{
    this->tree_.clear();
    this->tree_.shrink_to_fit();
    this->tree_.resize(2 * n + 10);
    this->elementsSize = n;
}
void segTree_::build(vector<int>& elements)
{
    this->resize(elements.size());
    this->build_(elements, 1, 0, this->elementsSize - 1);
}
void segTree_::build_(vector<int>& elements, int node, int left, int right)
{
    if(left == right)
    {
        this->tree_[node] = elements[left];
        return;
    }

    int middle = (left + right) / 2;

    this->build_(elements, node * 2, left, middle);
    this->build_(elements, node * 2 + 1, middle + 1, right);

    this->tree_[node] = max(this->tree_[node * 2], this->tree_[node * 2 + 1]);
}
void segTree_::update(int index, int val)
{
    this->update_(index, val, 1, 0, this->elementsSize - 1);
}
void segTree_::update_(int index, int val, int node, int left, int right)
{
    if(left == right)
    {
        this->tree_[node] = val;
        return;
    }

    int middle = (left + right) / 2;

    if(index <= middle)
    {
        this->update_(index, val, node * 2, left, middle);
    }
    else
    {
        this->update_(index, val, node * 2 + 1, middle + 1, right);
    }

    this->tree_[node] = max(this->tree_[node * 2], this->tree_[node * 2 + 1]);
}
int segTree_::rangeQuery(int leftQ, int rightQ)
{
    return this->rangeQuery_(leftQ, rightQ, 1, 0, this->elementsSize - 1);
}
int segTree_::rangeQuery_(int leftQ, int rightQ, int node, int left, int right)
{
    if(leftQ <= left && right <= rightQ)
    {
        return this->tree_[node];
    }
    else if(left <= rightQ && right >= leftQ)
    {   
        int middle = (left + right) / 2;

        return max(this->rangeQuery_(leftQ, rightQ, node * 2, left, middle), this->rangeQuery_(leftQ, rightQ, node * 2 + 1, middle + 1, right));
    }

    return -1;
}