Cod sursa(job #2938534)

Utilizator SalamanderHancu Robert Salamander Data 12 noiembrie 2022 10:51:31
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>
using namespace std;

/**
Se da un sir a1, a2, ..., an
Se dau de asemenea Q intrebari:
O intrebare este data prin
perechea i, j : Care este val. minima
din secventa a[i..j]

            1 2 3 4 5 6 7 8 9
        a = 6 9 2 5 8 3 1 7 4

rmq[0][i] = 6 9 2 5 8 3 1 7 4
rmq[1][i] = 6 2 2 5 3 1 1 4
rmq[2][i] = 2 2 2 1 1 1
rmq[3][i] = 1 1
3 6 : 2
1 9 : 1
2 8 : 1
1 5 : 2
4 5 : 3

rmq[3][1] = min(rmq[2][1],
                    rmq[2][5]);

3 23 : min(rmq[4][3], rmq[4][8])

RMQ (Range Minimum Query)
Construim o matrice cu log n linii
si n coloane
rmq[i][j] = valoarea minima din
intervalul de lungime 2^i care incepe
la pozitia j
(intervalul este a[j.. j+2^i-1])

5 4
1 5 6 4 3
2 4
1 2
3 5
1 4

*/
ifstream fin("rmq.in");
ofstream fout("rmq.out");
int a[100003], n;
int rmq[18][100003];
int len[100003];
/// len[i] = retine exponentul max e
/// cu pro. ca 2^e <= i
/// ex: len[10] = 3

int main()
{
    int i, j, L, e, Q, x, y;
    fin >> n >> Q;
    for (i = 1; i <= n; i++)
    {
        fin >> a[i];
        rmq[0][i] = a[i];
    }
    len[1] = 0;
    for (i = 2; i <= n; i++)
        len[i] = 1 + len[i / 2];
    for (i = 1; i <= len[n]; i++)
    {
        L = (1 << i);
        /// construim rmq[i][j], j=1..n-L+1
        for (j = 1; j <= n - L + 1; j++)
            rmq[i][j] = min(rmq[i-1][j],
                    rmq[i-1][j + L/2]);
    }
    for (i = 1; i <= Q; i++)
    {
        fin >> x >> y;
        e = len[y - x + 1];
        L = (1 << e);
        fout << min(rmq[e][x],rmq[e][y-L+1])<<"\n";
    }
    fout.close();
    return 0;
}