Cod sursa(job #2998712)

Utilizator AleXutzZuDavid Alex Robert AleXutzZu Data 9 martie 2023 21:28:51
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 kb
#include <iostream>
#include <vector>
#include <fstream>

struct RMQ {
private:
    std::vector<int> *v;
    std::vector<int> sectors;
    int root = 0;
public:

    explicit RMQ(std::vector<int> *const input) {
        this->v = input;

        size_t size = v->size() - 1;

        while (root * root <= size) root++;
        root--;

        for (int k = 0; k <= root; ++k) {
            int min = INT32_MAX;
            int min_pos = 0;
            for (int i = k * root + 1; i <= std::min<size_t>(size, (k + 1) * root); ++i) {
                if ((*input)[i] < min) {
                    min = (*input)[i];
                    min_pos = i;
                }
            }
            sectors.push_back(min_pos);
        }
    }

    int query(int left, int right) {
        int left_sector = (left - 1) / root;
        int right_sector = (right - 1) / root;

        int min_pos = 0;
        int min = INT32_MAX;
        for (int i = left_sector + 1; i <= right_sector - 1; ++i) {
            if ((*v)[sectors[i]] < min) {
                min = (*v)[sectors[i]];
                min_pos = sectors[i];
            }
        }

        for (int i = left; i <= std::min(right, (left_sector + 1) * root); ++i) {
            if ((*v)[i] < min) {
                min = (*v)[i];
                min_pos = i;
            }
        }


        for (int i = std::max(left, right_sector * root); i <= right; ++i) {
            if ((*v)[i] < min) {
                min = (*v)[i];
                min_pos = i;
            }
        }

        return min_pos;
    }

    void update(int pos, int value) {
        (*v)[pos] = value;
        int sector = pos / root;
        if (value < sectors[sector]) sectors[sector] = pos;
    }
};

int main() {
    std::ifstream input("rmq.in");
    std::ofstream output("rmq.out");

    std::vector<int> v;
    int n, q;
    input >> n >> q;
    v.resize(n + 1, 0);

    for (int i = 1; i <= n; ++i) input >> v[i];

    RMQ rmq(&v);

    while (q--) {
        int x, y;
        input >> x >> y;
        output << v[rmq.query(x, y)] << '\n';
    }

    return 0;
}