Cod sursa(job #1481889)

Utilizator crucerucalinCalin-Cristian Cruceru crucerucalin Data 5 septembrie 2015 14:54:37
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <cassert>

template<class Function>
class SegmentTree {
    // CLASS FUNCTIONS
    static std::size_t larger2Pow(std::size_t size) {
        auto ret = 1ul;

        while (ret < size)
            ret *= 2ul;

        return ret;
    }

    // DATA
    Function         d_folder;
    std::size_t      d_leaves;
    std::vector<int> d_data;

  public:
    ///
    // Constructs a new segment tree from the given 'values' and the manipulator
    // 'folder'.
    ///
    template<class Lambda>
    SegmentTree(const std::vector<int>& values, Lambda&& folder)
        : d_folder(std::forward<Lambda>(folder))
        , d_leaves{larger2Pow(values.size())}
        , d_data(d_leaves * 2)
    {
        for (auto i = 0ul; i < values.size(); ++i)
            d_data[d_leaves + i] = values[i];
        for (auto i = values.size(); i < d_leaves; ++i)
            d_data[d_leaves + i] = 0;
        for (auto i = d_leaves - 1; i > 0ul; --i)
            d_data[i] = d_folder(d_data[i * 2], d_data[i * 2 + 1]);
    }

    ///
    // Updates the value on position 'index'.
    ///
    void update(int index, int value) {
        index += d_leaves;
        d_data[index] = value;
        for (index /= 2; index > 0; index /= 2)
            d_data[index] = d_folder(d_data[index * 2], d_data[index * 2 + 1]);
    }

    ///
    // Makes a query on the given interval [from, to], using the manipulator
    // with which this segment tree has been constructed.
    ///
    int query(int from, int to) {
        auto ret = 0;

        from += d_leaves;
        to  += d_leaves;
        while (from <= to) {
            ret = d_folder(ret, d_data[from]);
            from = (from + 1) / 2;

            ret = d_folder(ret, d_data[to]);
            to = (to - 1) / 2;
        }

        return ret;
    }
};

int main() {
    std::ios_base::sync_with_stdio(false);

    std::ifstream inStream{"arbint.in"};
    std::ofstream outStream{"arbint.out"};

    int N, M;
    inStream >> N >> M;

    auto values = std::vector<int>(N);
    for (auto &value : values)
        inStream >> value;

    auto max = [](int lhs, int rhs) { return std::max(lhs, rhs); };
    SegmentTree<decltype(max)> segTree{values, max};

    for (auto i = 0; i < M; ++i) {
        int type, x, y;

        inStream >> type >> x >> y;
        if (!type)
            outStream << segTree.query(x - 1, y - 1) << "\n";
        else
            segTree.update(x - 1, y);
    }

    outStream << std::flush;
}