Cod sursa(job #1902724)

Utilizator misu007Pogonaru Mihai misu007 Data 4 martie 2017 19:14:56
Problema Range minimum query Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include <fstream>
#include <vector>
using namespace std;

class Problem {
    int const arraySize, queriesSize;
    vector<int> const array;
    vector<pair<int, int>> const queries;
public:
    Problem(int const arraySize, int const queriesSize,
            vector<int> const array, vector<pair<int, int>> const queries) :
                arraySize(arraySize), queriesSize(queriesSize),
                array(array), queries(queries){}

    int const& getASz() const {
        return arraySize;
    }

    int const& getQSz() const {
        return queriesSize;
    }

    vector<int> const& getA() const {
        return array;
    }

    vector<pair<int, int>> const& getQ() const {
        return queries;
    }
};

class IO {
    ifstream inputFile;
    ofstream outputFile;
public:
    //nu verific daca pot deschide fisierele
    IO(string const inputFile, string const outputFile) :
       inputFile(inputFile), outputFile(outputFile) { }

    ~IO() {
        inputFile.close();
        outputFile.close();
    }

    Problem const read() {
        int arraySize, queriesSize;
        int x, y;
        vector<int> array;
        vector<pair<int, int>> queries;

        inputFile >> arraySize >> queriesSize;
        for (int i = 0; i < arraySize; ++i) {
            inputFile >> x;
            array.push_back(x);
        }
        for (int i = 0; i < queriesSize; ++i) {
            inputFile >> x >> y;
            queries.push_back(pair<int, int>(x - 1, y - 1));
        }

        return Problem(arraySize, queriesSize, array, queries);
    }

    void write(int toWrite) {
        outputFile << toWrite << '\n';
    }
};

class Solution {
    //rmq[j] - vector cu minumul pe intervale de dimensiune j
    //rmq[j][i] - minimul de pe intervalul de dimensiune 2^j pornind din i
    vector<vector<int>> rmq;
    vector<int> log;
public:
    Solution(vector<int> array) {
        //rmq[0] - vectorul initial
        //cu minimul pe intervale de dimensiune 2^0 pornind din i
        rmq.push_back(array);
    }

    //pornim de la intervale mai mici
    //si cream solutiile pentru intervale mai mari
    void preprocess() {
        for (int j = 1; (1 << j) <= (int) rmq[0].size(); ++j) {
                rmq.push_back(vector<int>());
            for (int i = 0; i + (1 << j) - 1 < (int) rmq[0].size(); ++i) {
                rmq[j].push_back(min(rmq[j - 1][i],
                                     rmq[j - 1][i + (1 << (j - 1))]));
            }
        }
        log.push_back(0);
        log.push_back(0);
        for (int i = 2; i < (int) rmq[0].size(); ++i) {
            log.push_back(log[i >> 1] + 1);
        }
    }

    void solve(IO& io, Problem const& problem) {
        preprocess();
        int diff, mid, lg;
        for (auto it : problem.getQ()) {
            diff = it.second - it.first + 1;
            lg = log[diff];
            mid = diff - (1 << lg);

            io.write(min (rmq[lg][it.first], rmq[lg][it.first + mid]));
        }
    }
};

int main()
{
    IO io("rmq.in", "rmq.out");
    Problem pb = io.read();
    Solution solution(pb.getA());
    solution.solve(io, pb);
    return 0;
}