Cod sursa(job #3299733)

Utilizator christalknightChristian Micea christalknight Data 9 iunie 2025 20:25:35
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
// https://infoarena.ro/problema/arbint

#include <iostream>
#include <fstream>

using namespace std;

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

#define MAXN 100005 // log MAXN is approx. 17
#define INTERV_TREE_MAXN 262144 // 2 * 2 ^ log MAXN - 1 + some safety

void read_and_solve(void);
int build_tree(int vect[], int tree[], int treeIdx, int left, int right);
void update_tree(int tree[], int treeIdx, int left, int right, int targetIdx, int updateVal);
int find_max(int tree[], int treeIdx, int left, int right, int targetLeft, int targetRight);

int main() {
    read_and_solve();

    fin.close();
    fout.close();
    return 0;
}

void read_and_solve(void)
{
    int n, m, i, operation, left, right;

    fin >> n >> m;

    int vect[MAXN];
    int intervTree[INTERV_TREE_MAXN];

    for (i = 0; i < n; i++) 
        fin >> vect[i];

    build_tree(vect, intervTree, 0, 0, n - 1);

    while (m--) {
        fin >> operation >> left >> right;

        if (operation == 0){ // find the maximum values in the interval [left, right]
            fout << find_max(intervTree, 0, 0, n - 1, left - 1, right - 1) << "\n";
        }
        else // update the value at index left - 1 to the value right 
            update_tree(intervTree, 0, 0, n - 1, left - 1, right);
    }
}

int build_tree(int vect[], int tree[], int treeIdx, int left, int right) // builds the interval tree, starting from scratch
{   
    if (right == left) { // base case
        tree[treeIdx] = vect[left];
        return vect[left];
    }

    int mid = (left + right) / 2;
    int maxInInterval = max(build_tree(vect, tree, 2 * treeIdx + 1, left, mid), build_tree(vect, tree, 2 * treeIdx + 2, mid + 1, right));
    tree[treeIdx] = maxInInterval;
    return maxInInterval;
}

void update_tree(int tree[], int treeIdx, int left, int right, int targetIdx, int updateVal) 
{
    if (left == right) { // we have reached the wanted position
        tree[treeIdx] = updateVal;
        return;
    }

    int mid = (left + right) / 2;
    if (targetIdx <= mid)
        update_tree(tree, 2 * treeIdx + 1, left, mid, targetIdx, updateVal);
    else
        update_tree(tree, 2 * treeIdx + 2, mid + 1, right, targetIdx, updateVal);
    tree[treeIdx] = max(tree[treeIdx * 2 + 1], tree[treeIdx * 2 + 2]);
}

int find_max(int tree[], int treeIdx, int left, int right, int targetLeft, int targetRight)
{
    if (targetLeft <= left && targetRight >= right) // the current interval fits inside the queried one
        return tree[treeIdx];

    if (targetRight < left || targetLeft > right) // no intersection between the desired and current intervals
        return -1; // return minimal, impossible, insignificant value

    int mid = (left + right) / 2;
    int leftVal = find_max(tree, 2 * treeIdx + 1, left, mid, targetLeft, targetRight);
    int rightVal = find_max(tree, 2 * treeIdx + 2, mid + 1, right, targetLeft, targetRight);
    return max (leftVal, rightVal);
}