Cod sursa(job #940774)

Utilizator sebii_cSebastian Claici sebii_c Data 17 aprilie 2013 02:03:20
Problema Arbori de intervale Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <vector>

template <class T>
class segment_tree {
public:
    explicit segment_tree(int size);
    explicit segment_tree(const std::vector<T>& init_data);

    void update(int left, int right, T value);
    T query(int left, int right) const;

private:
    void _init(int node, int left, int right, const std::vector<T>& init_data);
    void _update(int node, int left, int right, int x, int y, T value);
    T _query(int node, int left, int right, int x, int y) const;

    int size;
    std::vector<T> tree;
};

template <class T>
segment_tree<T>::segment_tree(int _size): size(_size) {
    tree.resize(4 * _size + 10);
}

template <class T>
segment_tree<T>::segment_tree(const std::vector<T>& init_data): size(init_data.size()) {
    tree.resize(4 * init_data.size() + 10);
    _init(1, 1, init_data.size(), init_data);
}

template <class T>
void segment_tree<T>::update(int left, int right, T value) {
    _update(1, 1, size, left, right, value);
}

template <class T>
T segment_tree<T>::query(int left, int right) const {
    return _query(1, 1, size, left, right); 
}

template <class T>
void segment_tree<T>::_init(int node, int left, int right, const std::vector<T>& init_data) {
    if (left == right) {
        tree[node] = init_data[left];
    } else {
        int mid = left + (right - left) / 2;
        _init(2 * node, left, mid, init_data);
        _init(2 * node + 1, mid + 1, right, init_data);

        tree[node] = std::max(tree[2 * node], tree[2 * node + 1]);
    }
}

template <class T>
void segment_tree<T>::_update(int node, int left, int right, int x, int y, T value) {
    if (x <= left && right <= y) {
        tree[node] = value;
    } else {
        int mid = left + (right - left) / 2;

        if (x <= mid)
            _update(2 * node, left, mid, x, y, value);
        if (y > mid)
            _update(2 * node + 1, mid + 1, right, x, y, value);
        
        tree[node] = std::max(tree[2 * node], tree[2 * node + 1]);
    }
}

template <class T>
T segment_tree<T>::_query(int node, int left, int right, int x, int y) const {
    if (x <= left && right <= y) {
        return tree[node];
    } else {
        int mid = left + (right - left) / 2;

        T value = std::numeric_limits<T>::min();
        if (x <= mid)
            value = std::max(value, _query(2 * node, left, mid, x, y));
        if (y > mid)
            value = std::max(value, _query(2 * node + 1, mid + 1, right, x, y));

        return value;
    }
}

int main()
{
    std::ifstream fin("arbint.in");
    std::ofstream fout("arbint.out");

    int N, M;
    fin >> N >> M;

    std::vector<int> vec(N + 1);
    for (int i = 1; i <= N; ++i)
        fin >> vec[i];

    segment_tree<int> tree(vec);

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

        if (op == 0) {
            fout << tree.query(a, b) << std::endl;
        } else {
            tree.update(a, a, b);
        }
    }
    
    return 0;
}