Cod sursa(job #2865355)

Utilizator the_horoHorodniceanu Andrei the_horo Data 8 martie 2022 19:15:47
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <vector>


/* Defines */
using u32 = uint32_t;
using i32 = int32_t;

constexpr const char *inputFilename = "rmq.in";
constexpr const char *outputFilename = "rmq.out";


/* Function definitions */
void generateRmq (const std::vector<u32> &values);
u32 query (size_t left, size_t right);


/* Global variables */
std::array<std::vector<u32>, 50> rmq;


/* Functoin declarations */
void generateRmq (const std::vector<u32> &values) {
    rmq[0] = values;

    size_t i = 1;
    size_t step = 2;
    for (; step <= values.size(); ++ i, step *= 2) {
        rmq[i] = std::vector<u32>(values.size() - step + 1);

        for (size_t j = 0; j != rmq[i].size(); ++ j)
            rmq[i][j] = std::min(rmq[i - 1][j], rmq[i - 1][j + step / 2]);
    }
}

/* Queries [left, right) */
u32 query (size_t left, size_t right) {
    //std::clog << "RMQ: got query for " << left + 1 << ' ' << right + 1 << std::endl;
    size_t log = std::log2(right - left);
    //std::clog << "RMQ: the log is " << log << std::endl;
    size_t step = 1 << log;
    //std::clog << "RMQ: the step is " << step << std::endl;

    return std::min(rmq[log][left], rmq[log][right - step]);
}


int main () {
    std::ifstream input(inputFilename);
    input.exceptions(input.badbit | input.eofbit | input.failbit);
    std::ofstream output(outputFilename);
    output.exceptions(output.badbit | output.eofbit | output.failbit);

    size_t valuesCount;
    u32 queries;
    input >> valuesCount >> queries;

    std::vector<u32> values(valuesCount);
    for (auto &value: values)
        input >> value;

    generateRmq(values);

    for (u32 q = 0; q != queries; ++ q) {
        size_t left, right;
        input >> left >> right;
        -- left, -- right;

        ++ right;

        output << query(left, right) << '\n';
    }
}