13 template <
typename T,
typename BinOp,
typename Allocator = PolymorphicAllocator<T>>
49 noexcept(
noexcept(
container_type(std::move(rhs.data_), allocator)) &&
noexcept(BinOp(std::move(rhs.binOp_))))
58 template <std::forward_iterator It>
60 :
data_(std::distance(first, last) * 2, allocator),
binOp_(std::move(binOp)) {
70 :
SegmentTree(list.begin(), list.end(), std::move(binOp), allocator) {
77 return data_.get_allocator();
84 constexpr std::size_t
size()
const {
85 return data_.size() / 2;
97 constexpr void setPoint(std::size_t i,
const T& value) {
113 constexpr std::optional<T>
getRange(std::size_t first, std::size_t last)
const {
114 assert(first <= last &&
"invalid range");
115 std::size_t elementSize =
size();
116 first += elementSize;
119 std::optional<T> result{};
120 for (; first < last;) {
123 result =
data_[first];
133 result =
data_[last];
148 for (std::size_t i =
size(); i-- > 1;) {
150 std::size_t right = left + 1;
155 static constexpr bool hasParent(std::size_t i)
noexcept {
159 static constexpr std::size_t
getParent(std::size_t i)
noexcept {
160 assert(
hasParent(i) &&
"calling parent on the root node");
168 static constexpr std::size_t
getSibling(std::size_t i)
noexcept {
constexpr SegmentTree(std::initializer_list< T > list, BinOp binOp={}, const allocator_type &allocator={})
Initializer list constructor.
static constexpr std::size_t getSibling(std::size_t i) noexcept
constexpr SegmentTree(const SegmentTree &rhs, const allocator_type &allocator)
constexpr bool empty() const
Check if the segmeent tree is empty.
std::ptrdiff_t difference_type
constexpr void setPoint(std::size_t i, const T &value)
Set the new value at index i, then update the tree structure.
constexpr SegmentTree(SegmentTree &&rhs, const allocator_type &allocator) noexcept(noexcept(container_type(std::move(rhs.data_), allocator)) &&noexcept(BinOp(std::move(rhs.binOp_))))
constexpr SegmentTree(SegmentTree &&)=default
Vector< T, Allocator > container_type
constexpr std::size_t size() const
Return the number of input elements. This only counts the leaf node from the input.
constexpr std::optional< T > getRange(std::size_t first, std::size_t last) const
Query the value from [first, last) after applying the binary operator adjacent-pair wise....
static constexpr bool isRightChild(std::size_t i) noexcept
constexpr SegmentTree(const allocator_type &allocator) noexcept(noexcept(container_type(allocator)) &&noexcept(BinOp()))
static constexpr std::size_t getParent(std::size_t i) noexcept
static constexpr bool isLeftChild(std::size_t i) noexcept
const T & const_reference
allocator_type get_allocator() const noexcept
constexpr SegmentTree(It first, It last, BinOp binOp={}, const allocator_type &allocator={})
Iterator range constructor.
constexpr SegmentTree() noexcept(noexcept(container_type()) &&noexcept(BinOp()))
container_type::allocator_type allocator_type
constexpr SegmentTree(const SegmentTree &)=default
static constexpr std::size_t getLeftChild(std::size_t i) noexcept
constexpr void buildParent()
static constexpr bool hasParent(std::size_t i) noexcept
iterator begin() noexcept