Cod sursa(job #1869066)

Utilizator mihai.alphamihai craciun mihai.alpha Data 5 februarie 2017 16:04:10
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

FILE *fin = fopen("rmq.in", "r"), *fout = fopen("rmq.out", "w");

#define BUF 1 << 17
char buf[BUF];
int pos = BUF;

inline char next()  {
    if(pos == BUF)
        fread(buf, 1, BUF, fin), pos = 0;
    return buf[pos++];
}

inline int read()  {
    int x = 0, semn = 1;
    char ch = next();
    while(!isdigit(ch) && ch != '-')
        ch = next();
    if(ch == '-')
        semn = -1, ch = next();
    while(isdigit(ch))
        x = x * 10 + ch - '0', ch = next();
    return x * semn;
}

#define Nmax 100005
#define Log 8

int dp[Log][Nmax], lg[Nmax], v[Nmax];

inline int rmqmin(int v[], int a, int b)  {
    int k = lg[b - a + 1];
    return (v[dp[a][k]] <= v[dp[b - (1 << k) + 1][k]]) ? dp[a][k] : dp[b - (1 << k) + 1][k];
}

inline void construct(int v[], int N)  {
    for(int i = 2;i <= N;i++)  {
        lg[i] = lg[i >> 1] + 1;
    }
    for(int i = 0;i < N;i++)
        dp[i][0] = i;
    for(int j = 1;(1 << j) <= N;j++)
        for(int i = 1;i + (1 << j) <= N;i++)
            if(v[dp[i][j - 1]] < v[dp[i + (1 << (j - 1))][j - 1]])
                dp[i][j] = dp[i][j - 1];
            else
                dp[i][j] = dp[i + (1 << (j - 1))][j - 1];
}

int main()  {
    int M, N;
    N = read(), M = read();
    for(int i = 0;i < N;i++)
        v[i] = read();
    construct(v, N);
    for(int i = 0;i < M;i++)  {
        int a, b;
        a = read();
        b = read();
        a--, b--;
        fprintf(fout, "%d\n", v[rmqmin(v, a, b)]);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}