Cod sursa(job #3247284)

Utilizator Nicky_DumitracheNicolae Dumitrache Nicky_Dumitrache Data 6 octombrie 2024 19:38:04
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <iostream>

using namespace std;
const int N_MAX = 1e5;
const int LOG_MAX = 17;

int n; int v[1 + N_MAX];
void readInput(void) {
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> v[i];
}

int rmq[1 + LOG_MAX][1 + N_MAX];
int log_2[1 + N_MAX];

void compute_RMQ(void) {
    for (int i = 1; i <= n; i++)
        rmq[0][i] = v[i]; /// cand segmentul are lungime 1 evident ca minimul o sa fie acea valoare
    for (int e = 1; (1 << e) <= n; e++)
        for (int i = 1; i + (1 << e) - 1 <= n; i++)
            rmq[e][i] = min(rmq[e - 1][i], rmq[e - 1][i + (1 << (e - 1))]); /// impartim segmentul mare in jumatate si ne folosim de ce am calculat anterior
}

int query(int left, int right) {
    int lungime = right - left + 1;
    int putere = log_2[lungime];
    int answer = min(rmq[putere][left], rmq[putere][right - (1 << putere) + 1]);
    /// rmq[putere][left] = minimul pe prima parte, incercam sa mergem cat de mult se poate de la stanga la dreapta
    /// rmq[putere][right] = minimul pe a doua parte, incercam sa mergem cat de multe se poate de la dreapta la stanga
    return answer;
}

int main()
{

    readInput();
    log_2[1] = 0;
    for (int i = 2; i <= n; i++)
        log_2[i] = log_2[i / 2] + 1; /// preacalculam puterile pentru o anumita lungime
    compute_RMQ();
    int q; cin >> q;
    for (int i = 1; i <= q; i++) {
        int left, right; cin >> left >> right;
        cout << query(left, right) << "\n";
    }

    return 0;
}