Cod sursa(job #2708487)

Utilizator Casian_doispeChiriac Casian Casian_doispe Data 18 februarie 2021 19:57:39
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>
#include <cmath>

using namespace std;

ifstream cin("rmq.in") ;
ofstream cout("rmq.out") ;

/// range minimum query

/// programare dinamica, se tine o matrice unde m[f][e] este pozitia elem minim din intervalul f - e
/// initial consideram numai intervale de la f la f + 2^e, facem aceasta matrice

int m[100009][19], v[100009], p[30] ;

int pozmin(int st, int dr)
{

    int l = 1 ;

    while(p[l] <= dr - st + 1)
        l ++ ;

    l -- ;

    return min(m[st][l], m[dr + 1 - p[l]][l]) ;

}

int main()
{

    int n, q ;

    p[0] = 1 ;

    for(int f = 1 ; f <= 20 ; f ++)
        p[f] = p[f - 1] * 2 ;

    cin >> n >> q ;

    for(int f = 1 ; f <= n ; f ++)
        cin >> v[f] ;

    for(int e = 0 ; e <= 17 ; e ++)
        for(int f = 1 ; f <= n ; f ++)
        {
            if(!e)m[f][0] = v[f] ;
                else
                {

                    int b = INT_MAX ;

                    if(f + p[e - 1] <= n)b = m[f + p[e - 1]][e - 1] ;

                    m[f][e] = min(b, m[f][e - 1]) ;

                }
        }

        /*
    for(int f = 1 ; f <= n ; f ++)
    {

        m[f][0] = v[f] ;

        for(int e = 1 ; e <= 17 ; e ++)
        {

            if(m[f][e - 1] < m[f + p[e - 1]][e - 1])m[f][e] = m[f][e - 1] ;
                else m[f][e] = m[f + p[e - 1]][e - 1] ;

        }

        /// incercam sa setam dr constant

        int prev = f, l = 17 ;

        for(int t = 1, dr = f + p[t] ; t <= l ; t ++, dr = f + p[t])
        {

            /// mergem inclusiv cu prev, exclusiv cu dr

            m[f][t] = m[f][t - 1] ;

            for(int aux = prev ; aux < dr && aux <= n ; aux ++)
                m[f][t] = min(m[f][t], v[aux]) ;

            prev = dr ;

        }

    }
        */

    for(int f = 1 ; f <= q ; f ++)
    {

        int a, b ;

        cin >> a >> b ;

        cout << pozmin(a, b) << '\n' ;

    }

    return 0;
}
/*
10
12 14 7 1 6 8 9 10 2 4
*/