Cod sursa(job #3220946)

Utilizator MagicantPlusIuoras Andrei MagicantPlus Data 5 aprilie 2024 14:04:37
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.96 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <climits>
#include <vector>

using namespace std;

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

const long long INF = LLONG_MAX;

class SegmentTree
{
private:
    vector<long long> minseg;
    int n;

    void build_(int node, int left, int right, vector<long long>& nums);
    void update_(int node, int left, int right, int pos, long long num);
    long long rmq_(int node, int left, int right, int qleft, int qright);

public:
    void resize(int n);
    void build(vector<long long>& nums);
    void update(int pos, long long num);
    long long rmq(int qleft, int qright);
};

int main()
{
    int n, q;
    vector<long long> temp;
    SegmentTree nums;

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

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

    nums.build(temp);

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

        if(type == 0)
        {   
            a--;
            b--;
            fout << nums.rmq(a, b) << '\n';
        }
        else
        {
            a--;
            nums.update(a, b);
        }
    }

    return 0;
}

void SegmentTree::resize(int n)
{
    this->minseg.resize(4 * n + 1);
    this->n = n;
}
void SegmentTree::build(vector<long long>& nums)
{
    this->resize(nums.size());
    this->build_(1, 0, this->n - 1, nums);
}
void SegmentTree::update(int pos, long long num)
{
    this->update_(1, 0, this->n - 1, pos, num);
}
long long SegmentTree::rmq(int qleft, int qright)
{
    return this->rmq_(1, 0, this->n - 1, qleft, qright);
}
void SegmentTree::build_(int node, int left, int right, vector<long long>& nums)
{
    if(left == right)
    {
        this->minseg[node] = nums[left];
        return;
    }
    
    int middle = left + (right - left) / 2;

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

    this->minseg[node] = max(this->minseg[node * 2], this->minseg[node * 2 + 1]);
}
void SegmentTree::update_(int node, int left, int right, int pos, long long num)
{
    if(left == right)
    {
        this->minseg[node] = num;
        return;
    }

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

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

    this->minseg[node] = max(this->minseg[node * 2], this->minseg[node * 2 + 1]);
}
long long SegmentTree::rmq_(int node, int left, int right, int qleft, int qright)
{
    if(qright < left || right < qleft)
        return -1;
    
    if(qleft <= left && right <= qright)
        return this->minseg[node];

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

    return max(this->rmq_(node * 2, left, middle, qleft, qright), this->rmq_(node * 2 + 1, middle + 1, right, qleft, qright));
}