Cod sursa(job #2901037)

Utilizator 4N70N1U5Antonio Nitoi 4N70N1U5 Data 12 mai 2022 19:42:45
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

std::ifstream fin("rmq.in");
std::ofstream fout("rmq.out");

int N, M, V[100000][20];

void preprocess()
{
    for (int j = 1; (1 << j) < N; j++)
        for (int i = 0; i + (1 << (j - 1)) < N; i++)
            V[i][j] = std::min(V[i][j - 1], V[i + (1 << (j - 1))][j - 1]);
}

int query(int x, int y)
{
    int l = floor(log2(y - x + 1));
    return std::min(V[x][l], V[y - (1 << l) + 1][l]);
}

int main()
{
    fin >> N >> M;

    for (int i = 0; i < N; i++)
        fin >> V[i][0];

    preprocess();

    for (int i = 0; i < M; i++)
    {
        int x, y;
        fin >> x >> y;
        fout << query(x - 1, y - 1) << '\n';
    }
}

// int N, M, V[100000], RMQ[100000][20];
// // V - vectorul cu elemente.
// // RMQ - sparse table cu pozitiile in V ale elementelor minime.
// // RMQ[i][j] este pozitia elementului minim din intervalul care
// // incepe pozitia i si are lungime 2^j.

// void preprocess()
// {
//     for (int i = 0; i < N; i++)
//         RMQ[i][0] = i;
//     // Pentru intervalele de lungime 1, pozitia elementului
//     // minim este chiar pozitia elementului.

//     for (int j = 1; 1 << j <= N; j++)   
//         for (int i = 0; i + (1 << j) - 1 < N; i++)
//             RMQ[i][j] = (V[RMQ[i][j - 1]] <= V[RMQ[i + (1 << (j - 1))/*  - 1 */][j - 1]]) ? RMQ[i][j - 1] : RMQ[i + (1 << (j - 1))/*  - 1 */][j - 1];
//     // Determin pozitia elementului minim pentru intervale din
//     // ce in ce mai mari, pana cand intervalul ar fi prea lung
//     // si ar depasi finalul vectorului, dupa regula:
//     // RMQ[i][j] = RMQ[i][j - 1], daca V[RMQ[i][j - 1]] <= V[RMQ[i + (1 << (j - 1)) - 1][j - 1]]
//     // RMQ[i][j] = RMQ[i + (1 << (j - 1)) - 1][j - 1], altfel.
// }

// int query(int i, int j)
// {
//     // int k = round(log2(j - i + 1));
//     // int k = floor(log2(j - i + 1));
//     // int k = j - i + 1;
//     int k = 0;
//     while (1 << (k + 1) <= j - i + 1)
//         k++;
//     return std::min(V[RMQ[i][k]], V[RMQ[j - k + 1][k]]);
// }

// int main()
// {
//     fin >> N >> M;

//     for (int i = 0; i < N; i++)
//     {
//         fin >> V[i];
//     }

//     preprocess();

//     for (int i = 0; i < M; i++)
//     {
//         int x, y;
//         fin >> x >> y;
//         fout << query(x, y) << '\n';
//     }

//     return 0;
// }