Cod sursa(job #667159)

Utilizator ariel_roAriel Chelsau ariel_ro Data 22 ianuarie 2012 17:52:20
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <iostream>
#include <stdio.h>
#include <cmath>

using namespace std;

#define NMAX 100005
#define MMAX 18

int N, M, A[NMAX], Min[NMAX][MMAX];

void preprocess()
{
    // pt. intervale de 1 singur element
    for (int i = 0; i < N; i++)
    {
        Min[i][0] = i;
    }

    // pt. intervalele de la 2 elemente in sus
    for (int j = 1; 1 << j <= N; j++)
    {
        for (int i = 0; i + (1 << j) - 1 < N; i++)
        {
            if (A[Min[i][j - 1]] <= A[Min[i + (1 << (j - 1))][j - 1]])
            {
                Min[i][j] = Min[i][j - 1];
            }
            else
            {
                Min[i][j] = Min[i + (1 << (j - 1))][j - 1];
            }
        }
    }
}

int query(int low, int high)
{
    int k = (int)log2(high - low + 1);
    // maximul dintre 2 intervale care acopera [low, high]
    if (A[Min[low][k]] <= A[Min[high - (1 << k) + 1][k]])
    {
        return A[Min[low][k]];
    }
    else
    {
        return A[Min[high - (1 << k) + 1][k]];
    }
}

void solve()
{
    int low, high;
    scanf("%d %d",&N,&M);

    for (int i = 0; i < N; i++)
    {
        scanf("%d", &A[i]);
    }

    preprocess();

    for (int i = 0; i < M; i++)
    {
        scanf("%d %d", &low, &high);
        printf("%d\n", query(low - 1, high - 1));
    }
}

int main()
{
    freopen("rmq.in","r",stdin);
    freopen("rmq.out","w",stdout);

    solve();

    return 0;
}