Cod sursa(job #2209982)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 5 iunie 2018 12:53:00
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>

namespace algo {

template <typename T, typename C = std::less<T>>
class RangeMinimumQuery {
 public:
  RangeMinimumQuery(const std::vector<T>& v) : v_(v) {
    int n = static_cast<int>(v_.size());
    logarithm_.resize(n + 1);
    for (int i = 2; i <= n; ++i) {
      logarithm_[i] = logarithm_[i >> 1] + 1;
    }

    table_.resize(logarithm_[n] + 1);
    table_[0].resize(n);
    std::iota(table_[0].begin(), table_[0].end(), 0);
    for (int i = 1; i < static_cast<int>(table_.size()); ++i) {
      table_[i].resize(n - (1 << i) + 1);
      for (int j = 0; j + (1 << i) <= n; ++j) {
        table_[i][j] =
            GetMinIndex(table_[i - 1][j], table_[i - 1][j + (1 << (i - 1))]);
      }
    }
  }

  int QueryIndex(const int left_idx, const int right_idx) const {
    const int log_length = logarithm_[right_idx - left_idx + 1];
    return GetMinIndex(table_[log_length][left_idx],
                       table_[log_length][right_idx - (1 << log_length) + 1]);
  }

  T QueryValue(const int left_idx, const int right_idx) const {
    return v_[QueryIndex(left_idx, right_idx)];
  }

 private:
  int GetMinIndex(const int a, const int b) const {
    return compare_instance_(v_[a], v_[b]) ? a : b;
  }

  std::vector<T> v_;
  std::vector<int> logarithm_;
  std::vector<std::vector<int>> table_;
  C compare_instance_;
};

}  // namespace algo

int main()
{
    #ifdef INFOARENA
    freopen("rmq.in", "r", stdin);
    freopen("rmq.out", "w", stdout);
    #endif

    int n, q;
    scanf("%d%d", &n, &q);
    std::vector<int> v(n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &v[i]);
    }

    algo::RangeMinimumQuery<int> rmq(v);

    while (q--> 0) {
        int left_idx, right_idx;
        scanf("%d%d", &left_idx, &right_idx);
        --left_idx; --right_idx;
        printf("%d\n", rmq.QueryValue(left_idx, right_idx));
    }

    return 0;
}