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>
185 DCHECK_LT(begin, end);
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>
242 int begin,
int end)
const {
243 DCHECK_LT(begin, end);
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 {
250 return cmp(array[lhs_idx], array[rhs_idx]);
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< int64_t > & array() const
void MakeTableFromNewElements()
T RangeMinimum(int begin, int end) const
RangeMinimumQuery(std::vector< T > array, Compare cmp)
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.
RangeMinimumQuery(std::vector< T > array)
RangeMinimumQuery implementation.
In SWIG mode, we don't want anything besides these top-level includes.
int MostSignificantBitPosition32(uint32_t n)