This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/data-structure/segment-tree/point-mapping-range-fold-segment-tree.hpp"
PointMappingRangeFoldSegmentTree
のエイリアスとして SegmentTree
を提供している。
(1) SegmentTree< V >(usize n)
(2) SegmentTree< V >(usize n, VT v)
(3) SegmentTree< V >(vector< VT > vs)
V::identity()
となる。v
となる。vs
で初期化する。void build(vector< VT > vs)
列 $(a_0, a_1, \dots, a_{n-1})$ を vs
で初期化して再構築する。
vs.size()
が一致すること。usize size() const
扱っている列 $(a_0, a_1, \dots, a_{n - 1})$ の長さ $n$ を返す。
void set(usize i, VT x)
$a_i \leftarrow x$ で更新する。
(1) VT fold(usize i) const
(2) VT fold(usize l, usize r) const
(3) VT fold_all() const
V::identity()
が返る。気が向いたらそのうち実装する
気が向いたらそのうち実装する2
#pragma once
#include "src/cpp-template/header/rep.hpp"
#include "src/cpp-template/header/size-alias.hpp"
#include <cassert>
#include <vector>
namespace luz {
template < class value_structure >
class PointMappingRangeFoldSegmentTree {
using V = value_structure;
using VT = typename V::value_type;
std::vector< VT > tree;
void evaluate(usize index) {
tree[index] =
V::operation(tree[index << 1 | 0], tree[index << 1 | 1]);
}
public:
using value_type = VT;
PointMappingRangeFoldSegmentTree() = default;
explicit PointMappingRangeFoldSegmentTree(const usize n)
: tree(n * 2, V::identity()) {}
explicit PointMappingRangeFoldSegmentTree(const usize n, VT v)
: PointMappingRangeFoldSegmentTree(n) {
build(std::vector< VT >(n, v));
}
explicit PointMappingRangeFoldSegmentTree(
const std::vector< VT > &vs)
: PointMappingRangeFoldSegmentTree(vs.size()) {
build(vs);
}
void build(const std::vector< VT > &vs) {
usize n = vs.size();
assert(2 * n == tree.size());
std::copy(vs.begin(), vs.end(), tree.begin() + n);
for (usize index: rrep(1, n)) {
evaluate(index);
}
}
usize size() const {
return tree.size() / 2;
}
void set(usize index, const VT x) {
assert(index < size());
index += size();
tree[index] = x;
while (index != 1) {
index >>= 1;
evaluate(index);
}
}
VT fold(usize index) const {
assert(index < size());
return tree[index + size()];
}
VT fold(usize first, usize last) const {
assert(first <= last);
assert(last <= size());
first += size();
last += size();
VT fold_l = V::identity();
VT fold_r = V::identity();
while (first != last) {
if (first & 1) {
fold_l = V::operation(fold_l, tree[first]);
first += 1;
}
first >>= 1;
if (last & 1) {
last -= 1;
fold_r = V::operation(tree[last], fold_r);
}
last >>= 1;
}
return V::operation(fold_l, fold_r);
}
VT fold_all() const {
return (size() ? tree[1] : V::identity());
}
};
template < class value_structure >
using SegmentTree =
PointMappingRangeFoldSegmentTree< value_structure >;
} // namespace luz
#line 2 "src/data-structure/segment-tree/point-mapping-range-fold-segment-tree.hpp"
#line 2 "src/cpp-template/header/rep.hpp"
#line 2 "src/cpp-template/header/size-alias.hpp"
#include <cstddef>
namespace luz {
using isize = std::ptrdiff_t;
using usize = std::size_t;
} // namespace luz
#line 4 "src/cpp-template/header/rep.hpp"
#include <algorithm>
namespace luz {
struct rep {
struct itr {
usize i;
constexpr itr(const usize i) noexcept: i(i) {}
void operator++() noexcept {
++i;
}
constexpr usize operator*() const noexcept {
return i;
}
constexpr bool operator!=(const itr x) const noexcept {
return i != x.i;
}
};
const itr f, l;
constexpr rep(const usize f, const usize l) noexcept
: f(std::min(f, l)),
l(l) {}
constexpr auto begin() const noexcept {
return f;
}
constexpr auto end() const noexcept {
return l;
}
};
struct rrep {
struct itr {
usize i;
constexpr itr(const usize i) noexcept: i(i) {}
void operator++() noexcept {
--i;
}
constexpr usize operator*() const noexcept {
return i;
}
constexpr bool operator!=(const itr x) const noexcept {
return i != x.i;
}
};
const itr f, l;
constexpr rrep(const usize f, const usize l) noexcept
: f(l - 1),
l(std::min(f, l) - 1) {}
constexpr auto begin() const noexcept {
return f;
}
constexpr auto end() const noexcept {
return l;
}
};
} // namespace luz
#line 5 "src/data-structure/segment-tree/point-mapping-range-fold-segment-tree.hpp"
#include <cassert>
#include <vector>
namespace luz {
template < class value_structure >
class PointMappingRangeFoldSegmentTree {
using V = value_structure;
using VT = typename V::value_type;
std::vector< VT > tree;
void evaluate(usize index) {
tree[index] =
V::operation(tree[index << 1 | 0], tree[index << 1 | 1]);
}
public:
using value_type = VT;
PointMappingRangeFoldSegmentTree() = default;
explicit PointMappingRangeFoldSegmentTree(const usize n)
: tree(n * 2, V::identity()) {}
explicit PointMappingRangeFoldSegmentTree(const usize n, VT v)
: PointMappingRangeFoldSegmentTree(n) {
build(std::vector< VT >(n, v));
}
explicit PointMappingRangeFoldSegmentTree(
const std::vector< VT > &vs)
: PointMappingRangeFoldSegmentTree(vs.size()) {
build(vs);
}
void build(const std::vector< VT > &vs) {
usize n = vs.size();
assert(2 * n == tree.size());
std::copy(vs.begin(), vs.end(), tree.begin() + n);
for (usize index: rrep(1, n)) {
evaluate(index);
}
}
usize size() const {
return tree.size() / 2;
}
void set(usize index, const VT x) {
assert(index < size());
index += size();
tree[index] = x;
while (index != 1) {
index >>= 1;
evaluate(index);
}
}
VT fold(usize index) const {
assert(index < size());
return tree[index + size()];
}
VT fold(usize first, usize last) const {
assert(first <= last);
assert(last <= size());
first += size();
last += size();
VT fold_l = V::identity();
VT fold_r = V::identity();
while (first != last) {
if (first & 1) {
fold_l = V::operation(fold_l, tree[first]);
first += 1;
}
first >>= 1;
if (last & 1) {
last -= 1;
fold_r = V::operation(tree[last], fold_r);
}
last >>= 1;
}
return V::operation(fold_l, fold_r);
}
VT fold_all() const {
return (size() ? tree[1] : V::identity());
}
};
template < class value_structure >
using SegmentTree =
PointMappingRangeFoldSegmentTree< value_structure >;
} // namespace luz