Cod sursa(job #2036748)

Utilizator danny794Dan Danaila danny794 Data 11 octombrie 2017 06:28:50
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <cmath>
#include <cstdio>
#include <vector>

class RMQ {
 public:
  RMQ(int n) {
    matrix.resize(n);
    for (auto& row : matrix) {
      row.resize(1 + (int) (std::log(n) / std::log(2)));
      n--;
    }
  }

  void read() {
    for (auto& row : matrix) {
      scanf("%d", &row.front());
    }
  }

  void buildMatrix() {
    int pos = 0;
    for (int d = 0; d < matrix.front().size() - 1; d++) {
      for (int i = 0; i < matrix.size(); i++) {
        if (d >= matrix[i].size()) {
          break;
        }
        matrix[i][d + 1] = matrix[i][d];
        pos = i + (1 << d);
        if (pos < matrix.size() && matrix[pos].size() > d) {
          if (matrix[i][d + 1] > matrix[pos][d]) {
            matrix[i][d + 1] = matrix[pos][d];
          }
        }
      }
    }
  }

  int findMin(int a, int b) {
    if (a > b) {
      std::swap(a, b);
    }
    int d = (int) (std::log(b - a + 1) / std::log(2));
    int pos = 1 + b - (1 << d);
    if (matrix[a][d] > matrix[pos][d]) {
      return matrix[pos][d];
    }
    return matrix[a][d];
  }

 private:
  std::vector<std::vector<int>> matrix;
};

int main() {
  freopen("rmq.in", "r", stdin);
  freopen("rmq.out", "w", stdout);
  int n, m, a, b;
  scanf("%d %d", &n, &m);
  RMQ rmq(n);
  rmq.read();
  rmq.buildMatrix();
  while (m-- > 0) {
    scanf("%d %d", &a, &b);
    printf("%d\n", rmq.findMin(a - 1, b - 1));
  }
  return 0;
}