Cod sursa(job #902908)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 1 martie 2013 17:25:04
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <cstdio>
#include <cstring>
#include <cassert>

#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <map>

using namespace std;

typedef long long LL;
typedef vector<int>::iterator it;

const int oo = 0x3f3f3f3f;
const int MAX_N = 100005;
const int MAX_LOG = 17;

int N, Values[MAX_N], Log[MAX_N], RMQ[MAX_LOG][MAX_N];

inline bool Compare(const int a, const int b) {
    return Values[a] < Values[b];
}

void InitRMQ() {
    Log[1] = 0;
    for (int i = 2; i <= N; ++i)
        Log[i] = Log[i / 2] + 1;
    for (int i = 1; i <= N; ++i)
        RMQ[0][i] = i;
}

void BuildRMQ() {
    InitRMQ();
    for (int Step = 1, Length = 2; Step <= Log[N]; ++Step, Length *= 2) {
        for (int i = 1; i + Length - 1 <= N; ++i) {
            if (Compare(RMQ[Step - 1][i], RMQ[Step - 1][i + Length / 2]))
                RMQ[Step][i] = RMQ[Step - 1][i];
             else
                RMQ[Step][i] = RMQ[Step - 1][i + Length / 2];
        }
    }
}

inline int Query(int Left, int Right) {
    int Step = Log[Right - Left + 1];
    int Length = 1 << Step;
    if (Compare(RMQ[Step][Left], RMQ[Step][Right - Length + 1]))
        return RMQ[Step][Left];
    else
        return RMQ[Step][Right - Length + 1];
}

int main() {
    assert(freopen("rmq.in", "r", stdin));
    assert(freopen("rmq.out", "w", stdout));
    int NQ; assert(scanf("%d %d", &N, &NQ) == 2);
    for (int i = 1; i <= N; ++i)
        assert(scanf("%d", &Values[i]) == 1);
    BuildRMQ();
    for (; NQ > 0; --NQ) {
        int X, Y; assert(scanf("%d %d", &X, &Y) == 2);
        printf("%d\n", Values[Query(X, Y)]);
    }
    return 0;
}