Cod sursa(job #3367499)

Utilizator g.vladGociu Vlad g.vlad Data 8 octombrie 2026 11:45:00
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
/**
Arbori de intervale
Fie un vector A cu N elemente naturale. Asupra lui se vor face M operatii, codificate astfel in fisierul de intrare:
• 0 a b - Sa se determine maximul din intervalul [a,b] (maximul dintre valorile Ai cu a ≤ i ≤ b).
• 1 a b - Valoarea elementului de pe pozitia a va deveni b.

Date de intrare
Pe prima linie a fisierului de intrare se afla N si M. Pe urmatoarea linie se gasesc cele N elemente ale vectorului, iar urmatoarele M linii descriu operatia care trebuie efectuata.

Date de iesire
Pentru fiecare operatie de tip 0, se va afisa pe cate o linie maximul pentru intervalul cerut (in ordinea ceruta in fisierul de intrare).

Restrictii
1 ≤ M, N ≤ 100000
0 ≤ Ai ≤ 109 pentru 1 ≤ i ≤ N
Pentru operatia de tip 0: 1 ≤ a ≤ b ≤ N
Pentru operatia de tip 1: 1 ≤ a ≤ N si 1 ≤ b ≤ 109

Exemplu
arbint.in
5 5
4 3 5 6 1
0 1 3
1 3 2
0 2 3
1 4 2
0 1 5

arbint.out
5
3
4
*/

#include <iostream>

using namespace std;

constexpr size_t N_MAX = 100001;

struct ArbInt {
    short maxim[4 * N_MAX] = {};

    void update(
        size_t target,
        short value,
        size_t left = 0,
        size_t right = N_MAX - 1,
        size_t idx = 0
    ) {
        if ( left == right ) {
            this->maxim[idx] = value;
            return;
        }

        size_t middle = (left + right) / 2;

        if(middle < target) {
            this->update(target, value, left, middle - 1, idx << 1);
        }

        else {
            this->update(target, value, middle, right, (idx << 1) + 1);
        }
    }

    short maximum(
        size_t target_left,
        size_t target_right,
        size_t left = 0,
        size_t right = N_MAX - 1,
        size_t idx = 0
    ) {
        if ( left <= target_left && target_right <= right ) {
            return this->maxim[idx];
        }

        size_t middle = (left + right) / 2;
        short ret = 0;

        if (target_left  <  middle) ret += this->maximum(target_left, target_right, left, middle - 1, idx << 1);
        if (target_right >= middle) ret += this->maximum(target_left, target_right, middle, right, (idx << 1) + 1);

        return ret;
    }
};

int main() {
    size_t N, M;
    std::cin >> N >> M;
    ArbInt arbint;

    for(size_t n = 0; n < N; n += 1) {
        short read; std::cin >> read;
        arbint.update(n, read);
    }

    for(size_t m = 0; m < M; m += 1) {
        short ist, a, b; std::cin >> ist >> a >> b;
        switch (ist) {
        case 0:
            std::cout << arbint.maximum(a - 1, b - 1) << '\n';
            break;
        case 1:
            arbint.update(a - 1, b - 1);
            break;
        }
    }

    return 0;
}