Pagini recente » Cod sursa (job #2134384) | Cod sursa (job #2077012) | Cod sursa (job #1214526) | Cod sursa (job #3130955) | Cod sursa (job #1455596)
#include <iostream>
#include <fstream>
#include <assert.h>
#include <cmath>
const char IN[] = "rmq.in", OUT[] = "rmq.out";
const int NMAX = 100000;
const int LOGNMAX = 17;
inline int min(int a, int b) { return (a) < (b) ? (a) : (b); }
using namespace std;
int N, M;
int A[NMAX];
int PRE[NMAX - 1][LOGNMAX];
inline void preprocess() {
//PRE[i][j] = indexul minimului pe portiunea ce incepe la i si are dimensiune 2^j
//C.B. j = 0
for (int i = 0; i < N; ++i) PRE[i][0] = i;
//de la intervale mai mici la mai mari
for (int j = 1; (1 << j) < N; ++j) {
for (int i = 0; i + (1 << j) - 1 < N; ++i) {
//minimul din intervalul din stanga (i,2^(j-1)-1) si cel din dreapta
if (A[PRE[i][j - 1]] < A[PRE[i + (1 << (j - 1))][j - 1]])
PRE[i][j] = PRE[i][j - 1];
else PRE[i][j] = PRE[i + (1 << (j - 1))][j - 1];
}
}
}
inline void read_data() {
assert(freopen(IN, "r", stdin));
assert(freopen(OUT, "w", stdout));
assert(scanf("%d %d", &N, &M));
for (int i = 0; i < N; ++i) assert(scanf("%d", &A[i]));
preprocess();
for (int i = 0; i < M; ++i) {
int x, y;
assert(scanf("%d %d", &x, &y));
--x, --y;
int size = y - x + 1;
int interval = (int)log2(size);
//intervalul e impartit acum in doua: x..(x+(2^interval)-1)
//si y-(2^interval)..y+(2^interval)-1. Cele doua intervale
//acopera [x,y] si se suprapun complet daca [y-x+1] = 2^z
printf("%d\n", min(A[PRE[x][interval]], A[PRE[y - (1 << interval) + 1][interval]]));
}
fclose(stdout);
fclose(stdin);
}
int main() {
read_data();
return 0;
}