Cod sursa(job #2802316)

Utilizator Horia14Horia Banciu Horia14 Data 17 noiembrie 2021 21:43:14
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <fstream>
using namespace std;

class sparseTable {
private:
    int arrSIZE;
    int logSIZE;
    int* log;
    int* number;
    int** sparse;

public:
    void addNumber(int i, int val) {
        number[i] = val;
    }

    void buildLogArray(int Size) {
        log[1] = 0;
        for(int i = 2; i < Size; ++i)
            log[i] = 1 + log[i >> 1];
    }

    sparseTable(int Size) {
        arrSIZE = Size;
        logSIZE = 1 + Size;
        number = new int[Size];
        log = new int[1 + Size];
        buildLogArray(logSIZE);
        sparse = new int*[Size];
        for(int i = 0; i < Size; ++i)
            sparse[i] = new int[1 + log[Size]];
    }

    int getMin(int i, int j) {
        int firstValue = sparse[i][j - 1];
        int secondValue = sparse[i + (1 << (j - 1))][j - 1];
        if(number[firstValue] < number[secondValue])
            return firstValue;

        return secondValue;
    }

    void buildSparseTable() {
        for(int i = 0; i < arrSIZE; ++i)
            sparse[i][0] = i;

        for(int j = 1; (1 << j) <= arrSIZE; ++j)
            for(int i = 0; i + (1 << j) - 1 < arrSIZE; ++i)
                sparse[i][j] = getMin(i, j);
    }

    int RMQ(int Begin, int End) {
        int l = End - Begin + 1;
        int k = log[l];
        if(number[sparse[Begin][k]] < number[sparse[Begin + l - (1 << k)][k]])
            return number[sparse[Begin][k]];

        return number[sparse[Begin + l - (1 << k)][k]];
    }

    ~sparseTable() {
        delete[] log;
        delete[] number;
        for(int i = 0; i < arrSIZE; ++i)
            delete[] sparse[i];

        delete[] sparse;
    }

};

int main() {
    ifstream fin("rmq.in");
    ofstream fout("rmq.out");
    int n, m, x, y;
    fin >> n >> m;
    sparseTable* objSparseTable = new sparseTable(n);
    for(int i = 0; i < n; ++i) {
        fin >> x;
        objSparseTable->addNumber(i, x);
    }

    objSparseTable->buildSparseTable();

    for(int i = 0; i < m; ++i) {
        fin >> x >> y;
        fout << objSparseTable->RMQ(x - 1, y - 1) << "\n";
    }
    delete objSparseTable;

    return 0;
}