Cod sursa(job #3221495)

Utilizator MagicantPlusIuoras Andrei MagicantPlus Data 7 aprilie 2024 11:55:54
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.81 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

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

template<class T, class Operation> class SegmentTree
{
private:
    vector<T> segval;
    Operation op;
    int n;

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

public:
    void build(vector<T>& elements);
    void update(int pos, T val);
    T 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;
    vector<long long> temp;
    SegmentTree<long long, max_> nums;

    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 T, class Operation> void SegmentTree<T, Operation>::build(vector<T>& elements)
{
    this->resize(elements.size());
    this->build_(1, 0, this->n - 1, elements);
}
template<class T, class Operation> void SegmentTree<T, Operation>::update(int pos, T val)
{
    this->update_(1, 0, this->n - 1, pos, val);
}
template<class T, class Operation> T SegmentTree<T, Operation>::rangeVal(int left, int right)
{
    return this->rangeVal_(1, 0, this->n - 1, left, right);
}
template<class T, class Operation> void SegmentTree<T, Operation>::build_(int node, int left, int right, vector<T>& 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 T, class Operation> void SegmentTree<T, Operation>::update_(int node, int left, int right, int pos, T 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 T, class Operation> T SegmentTree<T, 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;
    T bestL, bestR;
    bool foundL = false, foundR = false;

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

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