Cod sursa(job #3312913)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 30 septembrie 2025 19:15:08
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.19 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <cassert>

using namespace std;

static constexpr int INF = ((int)(1e9) + 1);

namespace InParser
{
    static constexpr int BSIZE = (1 << 16);

    char buff[BSIZE];
    int pos = (BSIZE - 1);

    char get_char()
    {
        ++pos;

        if (pos == BSIZE)
        {
            int n = fread(buff, 1, BSIZE, stdin);
            if (n != BSIZE)
                for (int i = n; i < BSIZE; ++i)
                    buff[i] = 0;

            pos = 0;
        }

        return buff[pos];
    }

    int get_int()
    {
        int sign = (+1), answer = 0;

        for (;;)
        {
            char x = get_char();
            if (x == '-')
            {
                sign = (-1);
                break;
            }

            if ((x >= '0') && (x <= '9'))
            {
                answer = ((int)(x - '0'));
                break;
            }
        }

        for (;;)
        {
            char ch = get_char();

            if ((ch >= '0') && (ch <= '9'))
                answer = (answer * 10) + ((int)(ch - '0'));
            else
                break;
        }

        return (sign * answer);
    }
};

class Node
{
    int val;

    inline int my_max(const int x, const int y) const { return ((x > y) ? x : y); }

public:
    Node() : val(-INF) {}
    Node(const int x) : val(x) {}

    Node operator+(const Node &other)
    {
        return Node(my_max((*this).val, other.val));
    }

    void set_val(const int x) { val = x; }
    int get_val() const { return val; }
};

class SegmentTree
{
    int n;
    vector<Node> tree;

    void build(const int node, const int left, const int right, const vector<int> &input = {}, const int pos = 0, const int val = 0)
    {
        if (left > right)
            return;

        if (left == right)
        {
            if (!input.empty())
                tree[node].set_val(input[(left - 1)]);
            else
                tree[node].set_val(val);

            return;
        }

        int mid = ((left + right) >> 1);

        if (!input.empty())
        {
            build((node << 1), left, mid, input, pos, val),
                build(((node << 1) + 1), (mid + 1), right, input, pos, val);
        }
        else
        {
            if (pos <= mid)
                build((node << 1), left, mid, input, pos, val);
            else
                build(((node << 1) + 1), (mid + 1), right, input, pos, val);
        }

        tree[node] = tree[(node << 1)] + tree[((node << 1) + 1)];

        return;
    }

    Node ask(const int node, const int left, const int right, const int ql, const int qr)
    {
        if (left > right)
            return Node();

        if (ql <= left && right <= qr)
            return tree[node];

        int mid = ((left + right) >> 1);
        Node p_left, p_right;

        if (ql <= mid)
            p_left = ask((node << 1), left, mid, ql, qr);
        if (qr > mid)
            p_right = ask(((node << 1) + 1), (mid + 1), right, ql, qr);

        return (p_left + p_right);
    }

public:
    SegmentTree(const int size, const vector<int> &input)
    {
        n = size;
        tree.resize((n << 2) + 1);

        assert(n == (int)input.size());

        build(1, 1, n, input);

        return;
    }

    void update(const int pos, const int val)
    {
        build(1, 1, n, {}, pos, val);
        return;
    }

    int query(const int l, const int r)
    {
        return ask(1, 1, n, l, r).get_val();
    }

    void print()
    {
        for (int i = 1; i < (n << 1); ++i)
            cout << tree[i].get_val() << ' ';
        cout << '\n';

        return;
    }
};

int main()
{
    ios_base ::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("arbint.in", "r", stdin);
    freopen("arbint.out", "w", stdout);

    int n(InParser ::get_int()), m(InParser ::get_int());

    vector<int> v(n, 0);
    for (int i = 0; i < n; ++i)
        v[i] = InParser ::get_int();

    SegmentTree S(n, v);

    for (int t = 0; t < m; ++t)
    {
        short int type = ((short)InParser ::get_int());
        int a = InParser ::get_int(), b = InParser ::get_int();

        if (type == 0)
            printf("%d\n", S.query(a, b));
        else
            S.update(a, b);
    }

    return 0;
}