Cod sursa(job #2374064)

Utilizator stefanst77Luca Stefan Ioan stefanst77 Data 7 martie 2019 16:46:56
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <bits/stdc++.h>
#define nmax 100007

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

int n, m;
int a[nmax];    /// sirul de elemente
int p[nmax];    /// p[i] = k -> 2^k <= i
int rmq[18][nmax];
/**
rmq[i][j] = valoarea minima a intervalului
     de lungime 2^i care se termina la pozitia j
*/

int main()
{
    int i, j, r;
    fin >> n >> m;
    for (i = 1; i <= n; i++)
        fin >> a[i];

    /// initializari
    p[1] = 0; /// 2^0 = 1
    for (i = 2; i <= n; i++)
        p[i] = p[i / 2] + 1;

    for (i = 1; i <= n; i++)
        rmq[0][i] = a[i];
    /// minimul secventrei de lung 2^0 care incepe la poz i este a[i]

    /// rezolvare
    /// (1 << i) = 2^i
    /// rezolvam treptat impartind sirul in secvente de lungime 2^i
    for (i = 1; (1 << i) <= n; i++) /// gasim puterile lui 2 < n
    {
        for (j = (1 << i); j <= n; j++)
        {
            r = 1 << (i - 1);
        /// r este jumatate din j
            rmq[i][j]  = min (rmq[i - 1][j], rmq[i - 1][j - r]);
        }

    }

    /// afisare
    int x, y;
    for (i = 1; i <= m; i++)
    {
        fin >> x >> y;
        r = p[y - x + 1]; /// cel mai are exponent e a.i. 2^e < y - x + 1
        /// impartim secventa y - x + 1 in 2 secvente de lungime 2^e
        /**
        ex: x= 1, y = 9
    poz 1   2   3   4   5   6   7   8   9

    val 3   5   9   1   4   3   6   2   10
        |___|__________x____________|   |
            |_____________y_____________|
        */
        fout << min (rmq[r][x + (1 << r) - 1] , rmq[r][y]) << "\n";
    }
    for (i = 1; i <= n; i++)
    fin.close();
    fout.close();

    return 0;
}