Cod sursa(job #2921172)

Utilizator CiobaCatalinCioba Catalin CiobaCatalin Data 28 august 2022 00:31:17
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.09 kb
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

class IntervalTree
{
public:
    IntervalTree(vector<int> &v)
    {
        size = v.size();
        data.resize(4 * size);
        build(v, 0, 0, size - 1);
    }

    int maxRange(int left, int right)
    {
        return maxAux(0, 0, size - 1, left, right);
    }

    void update(int position, int value)
    {
        updateAux(0, 0, size - 1, position, value);
    }

private:
    int maxAux(int node, int left, int right, int intervalLeft, int intervalRight)
    {
        // cout << "MaxAux " << node << " [" << left << ", " << right << "] [" << intervalLeft << ", " << intervalRight << "]" << endl;
        if (intervalLeft <= left && intervalRight >= right)
        {
            return data[node];
        }
        int mid = (left + right) / 2;
        int a = 0, b = 0;
        if (intervalLeft <= mid)
        {
            a = maxAux(leftChild(node), left, mid, intervalLeft, intervalRight);
        }
        if (intervalRight >= mid + 1)
        {
            b = maxAux(rightChild(node), mid + 1, right, intervalLeft, intervalRight);
        }
        return max(a, b);
    }

    void updateAux(int node, int left, int right, int pos, int value)
    {
        // cout << node << " [" << left << ", " << right << "] pos=" << pos << " value=" << value << endl;
        if (pos > right || pos < left)
        {
            return;
        }
        if (left == right)
        {
            data[node] = value;
        }
        else
        {
            int mid = (left + right) / 2;
            if (pos <= mid)
            {
                updateAux(leftChild(node), left, mid, pos, value);
            }
            else
            {
                updateAux(rightChild(node), mid + 1, right, pos, value);
            }
            merge(node);
        }
        // cout << "data[" << node << "] = " << data[node] << endl;
    }

    void build(vector<int> &v, int p, int l, int r)
    {
        // cout << "Trying to build " << p << " [" << l << ", " << r << "]\n";
        if (l == r)
        {
            data[p] = v[l];
        }
        else
        {
            int m = (l + r) / 2;
            build(v, leftChild(p), l, m);
            build(v, rightChild(p), m + 1, r);
            merge(p);
        }
        // cout << "data[" << p << "] = " << data[p] << endl;
    }

    inline void merge(int p)
    {
        data[p] = max(data[leftChild(p)], data[rightChild(p)]);
    }

    inline int leftChild(int p)
    {
        return 2 * p + 1;
    }

    inline int rightChild(int p)
    {
        return 2 * p + 2;
    }

    vector<int> data;
    int size;
};

int main()
{
    ifstream in("arbint.in");
    ofstream out("arbint.out");

    int m, n;

    in >> n >> m;

    vector<int> v;
    v.resize(n);
    for (int i = 0; i < n; i++)
    {
        in >> v[i];
    }

    IntervalTree tree(v);

    int op, a, b;
    for (int i = 0; i < m; i++)
    {
        in >> op >> a >> b;

        if (op == 0)
        {
            out << tree.maxRange(a - 1, b - 1) << '\n';
        }
        else
        {
            tree.update(a - 1, b);
        }
    }
}