Cod sursa(job #2271519)

Utilizator veleanduAlex Velea veleandu Data 28 octombrie 2018 19:03:59
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.94 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

struct SegmentTree {
    struct Node {
        int interval_max;

        Node(int interval_max = 0) : interval_max(interval_max) {
        }

        void RebuildSelf(const Node& left, const Node& right) {
            interval_max = max(left.interval_max, right.interval_max);
        }
    };

    static const Node undefined_node;

    int n;
    vector<Node> els;

    void Init(const vector<Node>& initial_nodes) {
        n = initial_nodes.size();
        els = vector<Node>(4 * n, undefined_node);
        Init(1, 0, n - 1, initial_nodes);
    }

    void Init(int node, int left, int right, const vector<Node>& initial_nodes) {
        if (left == right) {
            els[node] = initial_nodes[left];
        } else {
            int mid = (left + right) / 2;
            Init(2 * node, left, mid, initial_nodes);
            Init(2 * node + 1, mid + 1, right, initial_nodes);
            els[node].RebuildSelf(
                    els[2 * node],
                    els[2 * node + 1]
            );
        }
    }

    void Update(int pos, const Node& new_node) {
        Update(1, 0, n - 1, pos, new_node);
    }

    void Update(int node, int left, int right, int pos, const Node& new_node) {
        if (left == right) {
            els[node] = new_node;
        } else {
            int mid = (left + right) / 2;
            if (pos <= mid) {
                Update(2 * node, left, mid, pos, new_node);
            } else {
                Update(2 * node + 1, mid + 1, right, pos, new_node);
            }

            els[node].RebuildSelf(
                    els[2 * node],
                    els[2 * node + 1]
            );
        }
    }

    Node Query(int c1, int c2) {
        return Query(1, 0, n - 1, c1, c2);
    }

    Node Query(int node, int left, int right, int c1, int c2) {
        if (right < c1 or c2 < left) {
            return undefined_node;
        }

        if (c1 <= left and right <= c2) {
            return els[node];
        }

        int mid = (left + right) / 2;
        auto l = Query(2 * node, left, mid, c1, c2);
        auto r = Query(2 * node + 1, mid + 1, right, c1, c2);
        Node ans;
        ans.RebuildSelf(l, r);
        return ans;
    }
};

const SegmentTree::Node SegmentTree::undefined_node(0);

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

    int n, q; cin >> n >> q;
    vector<SegmentTree::Node> initial_els(n);
    for (auto& itr : initial_els) {
        int x; cin >> x;
        itr.interval_max = x;
    }

    SegmentTree st;
    st.Init(initial_els);

    while (q--) {
        int type; cin >> type;
        if (type == 0) {
            int c1, c2; cin >> c1 >> c2;
            c1 -= 1;
            c2 -= 1;
            cout << st.Query(c1, c2).interval_max << '\n';
        } else {
            int pos, val; cin >> pos >> val;
            pos -= 1;
            st.Update(pos, SegmentTree::Node(val));
        }
    }
}