Cod sursa(job #2226272)

Utilizator inquisitorAnders inquisitor Data 30 iulie 2018 01:01:50
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <stdio.h>
#include <ctype.h>
#include <math.h>

const int INF = 1e9;
#define MAX_N 100000
#define MAX_SQ 317
#define MAX_LOG 8



int N, M;
int val[MAX_N + 1];
int lg[MAX_N + 3];
int left[MAX_N + 2];
int right[MAX_N + 2];
int rmq[MAX_LOG + 1][MAX_SQ + 1];
int shl[MAX_LOG + 1] = {1, 2, 4, 8, 16, 32, 64, 128, 256};

inline int MIN(const int X, const int Y) {
  return X < Y ? X : Y;
}

inline int naive(int a, int b) {
  int ret = INF;
  while (a <= b) {
    if (val[a] < ret) {
      ret = val[a];
    }
    a++;
  }
  return ret;
}

inline int look(const int a, const int b) {
  if (a <= b) {
    return MIN(rmq[lg[b - a + 1]][a], rmq[lg[b - a + 1]][b - shl[lg[b - a + 1]] + 1]);
  } else {
    return INF;
  }
}

int main(void) {

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

  int i, a, b, pass = 0;
  scanf("%d %d", &N, &M);
  int sq = sqrt(N);

  lg[1] = 0;
  for (i = 0; i < N; i++) {
    scanf("%d", &val[i]);
    if (i == pass) {
      left[i] = val[i];
      pass += sq;
    } else {
      left[i] = MIN(val[i], left[i - 1]);
    }
    lg[i + 2] = lg[(i + 2) >> 1] + 1;
  }

  pass = sq * ((N - 1) / sq);
  right[N] = INF;
  for (i = N - 1; i >= 0; i--) {
    if (i == pass - 1) {
      right[i] = val[i];
      pass -= sq;
    } else {
      right[i] = MIN(right[i + 1], val[i]);
    }
    if (i == pass) {
      rmq[0][pass / sq] = right[i];
    }
  }

  int j, tmp, size = (N - 1) / sq + 1;
  for (j = 1; j <= lg[size]; j++) {
    tmp = size - shl[j - 1];
    for (i = 0; i < tmp; i++) {
      rmq[j][i] = MIN(rmq[j - 1][i], rmq[j - 1][i + shl[j - 1]]);
    }
  }

  while (M) {
    scanf("%d", &a); --a;
    scanf("%d", &b); --b;
    tmp = a / sq;
    pass = b / sq;
    if (tmp == pass) {
      printf("%d\n", naive(a, b));
    } else {
      printf("%d\n", MIN(left[b], MIN(right[a], look(tmp + 1, pass - 1))));
    }
    M--;
  }

  return 0;
}