Cod sursa(job #2501422)

Utilizator preda.andreiPreda Andrei preda.andrei Data 29 noiembrie 2019 18:34:02
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#include <vector>

template <typename T>
class RmqVector {
public:
    explicit RmqVector(int size) {
        mins_.resize(size, {T()});
        logs_.resize(size + 1, 0);

        for (int i = 2; i <= size; i += 1) {
            logs_[i] = logs_[i / 2] + 1;
        }
    }

    void set(int pos, const T &value) {
        mins_[pos][0] = value;
    }

    T get(int left, int right) const {
        int len = right - left + 1;
        int log = logs_[len];
        int mid = left + (1 << log) - 1;

        return std::min(mins_[mid][log], mins_[right][log]);
    }

    void preprocess() {
        for (size_t i = 1; i < mins_.size(); i += 1) {
            for (int log = 0; log < logs_[i + 1]; log += 1) {
                auto mid = i - (1 << log);
                auto min_left = mins_[mid][log];
                auto min_right = mins_[i][log];

                auto new_min = std::min(min_left, min_right);
                mins_[i].push_back(new_min);
            }
        }
    }

private:
    std::vector<std::vector<T>> mins_;
    std::vector<int> logs_;
};

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

    int size, queries;
    fin >> size >> queries;

    RmqVector<int> rmq(size);
    for (int i = 0; i < size; i += 1) {
        int num;
        fin >> num;
        rmq.set(i, num);
    }
    rmq.preprocess();

    for (int i = 0; i < queries; i += 1) {
        int left, right;
        fin >> left >> right;

        auto res = rmq.get(left - 1, right - 1);
        fout << res << "\n";
    }

    return 0;
}