Cod sursa(job #3128979)

Utilizator Alexco2003Codarcea Alexandru-Christian Alexco2003 Data 11 mai 2023 20:21:09
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.75 kb
#include <iostream>
#include <fstream>
using namespace std;

const int MAX_N = 100001;

/// Structure to represent a node in the interval tree
struct Node
{
    int maximum;  /// Maximum grade in the range represented by the node
    int value;   /// Value to update the element at position a
};

Node tree[4 * MAX_N];  /// Interval tree
int elements[MAX_N];    /// Array to store the elements

/// Function to build the interval tree
void buildTree(int node, int start, int end)
{
    if (start == end)
    {
        /// Leaf node, store the element value
        tree[node].maximum = elements[start];
        tree[node].value = -1; /// No update value
        return;
    }

    int mid = (start + end) / 2;

    /// Recursively build the left and right subtrees
    buildTree(2 * node, start, mid);
    buildTree(2 * node + 1, mid + 1, end);

    /// Update the current node with the maximum element of its children
    tree[node].maximum = max(tree[2 * node].maximum, tree[2 * node + 1].maximum);
    tree[node].value = -1;  /// No update value
}

/// Function to propagate the update value
void propagateUpdate(int node)
{
    if (tree[node].value != -1)
    {
        /// Update the element value
        tree[node].maximum = tree[node].value;

        if (2 * node < 4 * MAX_N)
        {
            /// Propagate the update value to the children nodes
            tree[2 * node].value = tree[node].value;
            tree[2 * node + 1].value = tree[node].value;
        }

        /// Reset the update value of the current node
        tree[node].value = -1;
    }
}

/// Function to update the element at position a
void updateElement(int node, int start, int end, int a, int b)
{
    propagateUpdate(node);

    if (start == end)
    {
        /// Leaf node, update the element value
        tree[node].maximum = b;
        return;
    }

    int mid = (start + end) / 2;

    if (a <= mid)
    {
        /// Update the element in the left subtree
        updateElement(2 * node, start, mid, a, b);
    }
    else
    {
        /// Update the element in the right subtree
        updateElement(2 * node + 1, mid + 1, end, a, b);
    }

    /// Update the current node with the maximum element of its children
    tree[node].maximum = max(tree[2 * node].maximum, tree[2 * node + 1].maximum);
}

/// Function to query the maximum element in a given range
int queryMaxElement(int node, int start, int end, int l, int r)
{
    propagateUpdate(node);

    if (start > r || end < l)
        return -1;

    if (start >= l && end <= r)
        return tree[node].maximum;

    int mid = (start + end) / 2;
    /// Partial overlap, query the maximum element from the left and right subtrees
    int left = queryMaxElement(2 * node, start, mid, l, r);
    int right = queryMaxElement(2 * node + 1, mid + 1, end, l, r);

    /// Return the maximum element
    if (left == -1)
        return right;
    if (right == -1)
        return left;
    return max(left, right);
}

int main()
{
    int N, M;
    ifstream f1("arbint.in");
    ofstream f2("arbint.out");
    f1 >> N >> M;

    for (int i = 1; i <= N; i++)
    {
        f1 >> elements[i];
    }

    /// Build the interval tree
    buildTree(1, 1, N);

    while (M--)
    {
        int op, a, b;
        f1 >> op >> a >> b;

        if (op == 0)
        {
            /// Find the maximum element in the interval [a, b]
            int maxElement = queryMaxElement(1, 1, N, a, b);
            f2 << maxElement << endl;
        }
        else if (op == 1)
        {
            /// Update the element at position a with value b
            updateElement(1, 1, N, a, b);
        }
    }

    f1.close();
    f2.close();
    return 0;
}