Cod sursa(job #2222855)

Utilizator nurof3nCioc Alex-Andrei nurof3n Data 18 iulie 2018 12:05:39
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include <fstream>

using namespace std;

ifstream in("rmq.in");
ofstream out("rmq.out");

const int MAXN = 100001;
const int LOGMAXN = 18;
int N, M, v[MAXN];
int RMQ[MAXN][LOGMAXN]; //RMQ[i][j] reprezinta indicele celui mai mic element din v pe intervalul (i, i + 2 ^ j - 1)
int lg[MAXN]; //valorile logaritmilor in baza 2

void logaritmi()
{
    lg[1] = 0;
    for (int i = 2; i <= N; i++)
        lg[i] = lg[i / 2] + 1;
}
void compute_rmq()
{
    for (int i = 0; i <= N; i++)
        RMQ[i][0] = i;
    for (int j = 1; (1 << j) <= N; j++) //2 ^ j reprezinta lungimea intervalului pe care facem minimul
        for (int i = 0; i + (1 << j) - 1 <= N; i++) //i reprezinta capatul din stamga al intervalului
            if (v[RMQ[i][j - 1]] <= v[RMQ[i + (1 << (j - 1))][j - 1]])
                RMQ[i][j] = RMQ[i][j - 1];
            else
                RMQ[i][j] = RMQ[i + (1 << (j - 1))][j - 1];
}
int range_minimum_query(int i, int j)
{
    int log = lg[j - i + 1];
    return min(v[RMQ[i][log]], v[RMQ[j - (1 << log) + 1][log]]);
}
int main()
{
    in >> N >> M;
    logaritmi();
    for (int i = 1; i <= N; i++)
        in >> v[i];
    compute_rmq();
    int x, y;
    for (int i = 1; i <= M; i++)
    {
        in >> x >> y;
        out << range_minimum_query(x, y) << '\n';
    }
    return 0;
}