Cod sursa(job #3131784)

Utilizator alisavaAlin Sava alisava Data 21 mai 2023 14:00:57
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <bits/stdc++.h>

#define lung(x) ( 1 << (x) )

using namespace std;

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

int M[100005][20], A[100005], N;
///in M[i][j] tinem pozitia minimului pt intervalul [i,i+lung(j)-1]
int logaritm[100005];

void generateLog() {
    for (int i = 2; i <= N; i++)
        logaritm[i] = logaritm[i / 2] + 1;
}


void formareM() {
    int i, j;
    ///------------------------------------------------
    for (i = 1; i <= N; i++)
        M[i][0] = i;
    ///------------------------------------------------
    for (j = 1; lung(j) <= N; j++)
        for (i = 1; i + lung(j) - 1 <= N; i++)
            if (A[M[i][j - 1]] ///minimul primului interval
                < A[M[i + lung(j - 1)][j - 1]]) ///minimul celui de al 2 lea interval
                M[i][j] = M[i][j - 1]; /// se atribuiie valoarea primului interval din care se formeaza
            else
                M[i][j] = M[i + (lung(j - 1))][j - 1];/// se atribuie valoarea celui de al doilea interval

}

int query(int x, int y) {

    int k = logaritm[y - x + 1];
    int start2 = y - lung(k) + 1; //inceputul celui de-al doilea interval
    /// M[x][k]  --> minimul pt primul int
    /// M[y-lung(k)+1]][k] --> minimul pt int 2
    ///cele 2 pot fi intersectate

    if (A[M[x][k]] <= A[M[start2][k]])
        return A[M[x][k]];
    else
        return A[M[start2][k]];
}


int main() {
    int q, x, y;
    fin >> N >> q;
    for (int i = 1; i <= N; i++)
        fin >> A[i];
    formareM();
    generateLog();
    for (int i = 1; i <= q; i++) {
        fin >> x >> y;
        fout << query(x, y) << "\n";
    }
    return 0;
}