Cod sursa(job #1902760)

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

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

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

    int& getQSz() {
        return queriesSize;
    }

    void decQSz() {
        -- (this -> queriesSize);
    }

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

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;
        vector<int> array;

        inputFile >> arraySize >> queriesSize;
        for (int i = 0; i < arraySize; ++i) {
            inputFile >> x;
            array.push_back(x);
        }

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

    pair<int, int> nextQuery(Problem& pb) {
        if (pb.getQSz()) {
            int x, y;
            inputFile >> x >> y;
            pb.decQSz();
            return pair<int, int>(x - 1, y - 1);
        }
        return pair<int, int>(-1, -1);
    }

    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& problem) {
        preprocess();
        int diff, mid, lg;
        pair<int, int> query = io.nextQuery(problem);
        while (query.first != -1) {
            diff = query.second - query.first + 1;
            lg = log[diff];
            mid = diff - (1 << lg);

            io.write(min (rmq[lg][query.first], rmq[lg][query.first + mid]));
            query = io.nextQuery(problem);
        }
    }
};

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