Cod sursa(job #3150294)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 15 septembrie 2023 23:34:53
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include <fstream>
#include <vector>
#include <functional>

template<typename T>
class Merger {};

template<>
class Merger<int> {
public:
    int operator()(const int& a, const int &b) {
        return std::max(a, b);
    }
};

template<typename T>
class SegmentTree {
private:
    int n;
    std::vector<T> nodes;
    Merger<T> f;

    void build(int node, int l, int r, const std::vector<T>& v);

    void update(int node, int l, int r, int pos, const T& v);

    T query(int node, int l, int r, int ql, int qr);
public:
    SegmentTree(const std::vector<T>& v, const Merger<T>& f);

    void Update(int pos, const T& v);

    T Query(int l, int r);
};

template<typename T>
void SegmentTree<T>::build(int node, int l, int r, const std::vector<T>& v) {
    if (l == r) {
        nodes[node] = v[l - 1];
        return;
    }

    int mid = (l + r) >> 1;
    build(node << 1, l, mid, v);
    build(node << 1 | 1, mid + 1, r, v);

    nodes[node] = f(nodes[node << 1], nodes[node << 1 | 1]);
}

template<typename T>
void SegmentTree<T>::update(int node, int l, int r, int pos, const T& v) {
    if (l == r) {
        nodes[node] = v;
        return;
    }

    int mid = (l + r) >> 1;
    if (pos <= mid) update(node << 1, l, mid, pos, v);
    else update(node << 1 | 1, mid + 1, r, pos, v);

    nodes[node] = f(nodes[node << 1], nodes[node << 1 | 1]);
}

template<typename T>
T SegmentTree<T>::query(int node, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return nodes[node];

    int mid = (l + r) >> 1;
    if (qr <= mid) return query(node << 1, l, mid, ql, qr);
    if (ql > mid) return query(node << 1 | 1, mid + 1, r, ql, qr);

    T a = query(node << 1, l, mid, ql, mid), b = query(node << 1 | 1, mid + 1, r, mid + 1, qr);
    return f(a, b);
}

template<typename T>
SegmentTree<T>::SegmentTree(const std::vector<T> &v, const Merger<T>& f) {
    n = (int)v.size();
    nodes.resize(4 * n);

    build(1, 1, n, v);
}

template<typename T>
void SegmentTree<T>::Update(int pos, const T& v) {
    update(1, 1, n, pos, v);
}

template<typename T>
T SegmentTree<T>::Query(int l, int r) {
    return query(1, 1, n, l, r);
}


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

    int n, m; cin >> n >> m;
    std::vector<int> v(n);
    for (int i = 0; i < n; i++) cin >> v[i];


    SegmentTree<int> seg_tree(v, Merger<int>());

    for (int i = 0; i < m; i++) {
        int t, a, b;
        cin >> t >> a >> b;
        if (t == 0) cout << seg_tree.Query(a, b) << '\n';
        else seg_tree.Update(a, b);
    }

    return 0;
}