Cod sursa(job #2334637)

Utilizator igsifvevc avb igsi Data 2 februarie 2019 19:38:25
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iterator>
#include <limits>
#include <vector>

std::vector<int> read(std::istream &in);
std::vector<std::vector<int>> preprocess_rmq(const std::vector<int> &);
int find_min(const int, const int, const std::vector<std::vector<int>> &);

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

    std::vector<std::vector<int>> rmq = preprocess_rmq(read(fin));

    for (int l, r; fin >> l >> r;)
    {
        fout << find_min(l - 1, r - 1, rmq) << '\n';
    }

    return 0;
}

int find_min(const int l, const int r, const std::vector<std::vector<int>> &rmq)
{
    int k{std::log2(r - l + 1)};

    return std::min(rmq[l][k], rmq[r - (1 << k) + 1][k]);
}

std::vector<std::vector<int>> preprocess_rmq(const std::vector<int> &in)
{
    int maxlog2{static_cast<int>(std::log2(in.size())) + 1};
    std::vector<std::vector<int>> rmq(in.size(), std::vector<int>(maxlog2, std::numeric_limits<int>::max()));

    for (size_t i = 0; i < in.size(); ++i)
    {
        rmq[i][0] = in[i];
    }

    for (int i = in.size() - 1; i >= 0; --i)
    {
        for (int k = 1; i + (1 << k) - 1 < in.size(); ++k)
        {
            rmq[i][k] = std::min(rmq[i][k - 1], rmq[i + (1 << (k - 1))][k - 1]);
        }
    }

    return rmq;
}

std::vector<int> read(std::istream &in)
{
    int n, m;
    in >> n >> m;

    std::vector<int> V;
    std::copy_n(std::istream_iterator<int>(in), n, std::back_inserter(V));

    return V;
}