73#ifndef OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_
74#define OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_
82#include "absl/log/check.h"
86template <
typename T,
typename Compare = std::less<T>>
109 void PushBack(T element) { cache_[0].push_back(element); }
125 for (
auto& row : cache_) row.clear();
129 const std::vector<T>&
array()
const;
133 std::vector<std::vector<T>> cache_;
139template <
typename T,
typename Compare = std::less<T>>
154 const std::vector<T>&
array()
const;
158 static std::vector<int> CreateIndexVector(
int n);
159 struct IndexComparator {
160 bool operator()(
int lhs_idx,
int rhs_idx)
const;
161 const std::vector<T>
array;
168template <
typename T,
typename Compare>
172template <
typename T,
typename Compare>
175 : cache_(2), cmp_(
std::move(cmp)) {
178 cache_[0] = std::move(
array);
182template <
typename T,
typename Compare>
186 DCHECK_LE(
end, cache_[1].size());
187 DCHECK_EQ(cache_[0].size(), cache_[1].size());
189 DCHECK_LT(layer, cache_.size());
190 const int window = 1 << layer;
191 const T* row = cache_[layer].data();
192 DCHECK_LE(
end - window, cache_[layer].size());
193 return std::min(row[
begin], row[
end - window], cmp_);
200template <
typename T,
typename Compare>
202 const int new_size = cache_[0].size();
203 const int old_size = cache_[1].size();
204 if (old_size >= new_size)
return;
208 if (cache_.size() < num_rows) cache_.resize(num_rows);
210 cache_[1].resize(new_size);
212 for (
int row = 1; row < num_rows; ++row) {
213 const int half_window = 1 << (row - 1);
214 const int last_col = new_size - 2 * half_window;
215 if (cache_[row].size() <= last_col) cache_[row].resize(last_col + 1);
216 for (
int col = old_size; col <= last_col; ++col) {
217 cache_[row][col] = std::min(cache_[row - 1][col],
218 cache_[row - 1][col + half_window], cmp_);
223template <
typename T,
typename Compare>
229template <
typename T,
typename Compare>
231 std::vector<T>
array)
234template <
typename T,
typename Compare>
237 : cmp_({std::move(
array), std::move(cmp)}),
238 rmq_(CreateIndexVector(cmp_.array.size()), cmp_) {}
240template <
typename T,
typename Compare>
244 return rmq_.RangeMinimum(
begin,
end);
247template <
typename T,
typename Compare>
248inline bool RangeMinimumIndexQuery<T, Compare>::IndexComparator::operator()(
249 int lhs_idx,
int rhs_idx)
const {
253template <
typename T,
typename Compare>
254std::vector<int> RangeMinimumIndexQuery<T, Compare>::CreateIndexVector(
int n) {
255 std::vector<int> result(n, 0);
256 std::iota(result.begin(), result.end(), 0);
260template <
typename T,
typename Compare>
RangeMinimumIndexQuery(const RangeMinimumIndexQuery &)=delete
This type is neither copyable nor movable.
RangeMinimumIndexQuery(std::vector< T > array)
RangeMinimumIndexQuery implementation.
int GetMinimumIndexFromRange(int begin, int end) const
const std::vector< T > & array() const
Returns the original array.
RangeMinimumIndexQuery & operator=(const RangeMinimumIndexQuery &)=delete
const std::vector< T > & array() const
Returns the concatenated sequence of all elements in all arrays.
void MakeTableFromNewElements()
T RangeMinimum(int begin, int end) const
RangeMinimumQuery & operator=(const RangeMinimumQuery &)=delete
RangeMinimumQuery(const RangeMinimumQuery &)=delete
This type is neither copyable nor movable.
int TableSize() const
Returns the number of elements in sparse tables, excluding new elements.
In SWIG mode, we don't want anything besides these top-level includes.
ClosedInterval::Iterator end(ClosedInterval interval)
int MostSignificantBitPosition32(uint32_t n)
ClosedInterval::Iterator begin(ClosedInterval interval)