Cod sursa(job #3221546)

Utilizator MagicantPlusIuoras Andrei MagicantPlus Data 7 aprilie 2024 13:19:04
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

template<class type, class operation> class SegmentTree
{
private:
    vector<type> segval;
    operation op;
    int n;

    void build_(int node, int left, int right, vector<type>& elements);
    void update_(int node, int left, int right, int pos, type val);
    type rangeVal_(int node, int left, int right, int qleft, int qright);
    void resize(int n);

public:
    void build(vector<type>& elements);
    void update(int pos, type val);
    type rangeVal(int left, int right);
};

int main()
{
    struct max_
    {
        long long operator()(long long a, long long b)
        {
            return max(a, b);
        }
    };

    int n, q;
    SegmentTree<long long, max_> nums;
    vector<long long> temp;

    fin >> n >> q;
    temp.resize(n);

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

    nums.build(temp);

    for(int i = 0; i < q; i++)
    {
        long long type, a, b;

        fin >> type >> a >> b;

        if(type == 0)
        {
            a--;
            b--;

            fout << nums.rangeVal(a, b) << '\n';
        }
        else
        {
            a--;

            nums.update(a, b);
        }
    }

    return 0;
}

template<class type, class operation> void SegmentTree<type, operation>::build(vector<type>& elements)
{
    this->resize(elements.size());
    this->build_(1, 0, this->n - 1, elements);
}
template<class type, class operation> void SegmentTree<type, operation>::update(int pos, type val)
{
    this->update_(1, 0, this->n - 1, pos, val);
}
template<class type, class operation> type SegmentTree<type, operation>::rangeVal(int left, int right)
{
    return this->rangeVal_(1, 0, this->n - 1, left, right);
}
template<class type, class operation> void SegmentTree<type, operation>::build_(int node, int left, int right, vector<type>& elements)
{
    if(left == right)
    {
        this->segval[node] = elements[left];
        return;
    }

    int middle = left + (right - left) / 2;

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

    this->segval[node] = this->op(this->segval[node * 2], this->segval[node * 2 + 1]);
}
template<class type, class operation> void SegmentTree<type, operation>::update_(int node, int left, int right, int pos, type val)
{
    if(left == right)
    {
        this->segval[node] = val;
        return;
    }

    int middle = left + (right - left) / 2;

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

    this->segval[node] = this->op(this->segval[node * 2], this->segval[node * 2 + 1]);
}
template<class type, class operation> type SegmentTree<type, operation>::rangeVal_(int node, int left, int right, int qleft, int qright)
{
    if(qleft <= left && right <= qright)
    {
        return this->segval[node];
    }

    int middle = left + (right - left) / 2;
    type bestL, bestR;
    bool foundL = false, foundR = false;

    if(qleft <= middle)
    {
        foundL = true;
        bestL = this->rangeVal_(node * 2, left, middle, qleft, qright);
    }
    
    if(qright >= middle + 1)
    {
        foundR = true;
        bestR = this->rangeVal_(node * 2 + 1, middle + 1, right, qleft, qright);
    }

    if(foundL && foundR)
    {
        return this->op(bestL, bestR);
    }
    else if(foundL)
    {
        return bestL;
    }
    else
    {
        return bestR;
    }
}
template<class type, class operation> void SegmentTree<type, operation>::resize(int n)
{
    this->segval.resize(4 * n + 1);
    this->n = n;
}