This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/data-structure/fenwick-tree.hpp"
長さ $n$ の列 $(a_0, a_1, \cdots, a_{n-1})$ に対し
を $O(\log n)$ で求めることが可能なデータ構造
(1) FenwickTree<T>(usize n)
(2) FenwickTree<T>(const std::vector<T> &as)
T()
で初期化する。as[i]
として初期化する。void add(usize k, const T &v)
$a_{k} \leftarrow a_{k} + v$ で更新を行う。
T sum(usize l, usize r) const
$a_{l} + a_{l+1} + \cdots + a_{r-1}$ を返す。
#pragma once
#include "src/cpp-template/header/rep.hpp"
#include "src/cpp-template/header/size-alias.hpp"
#include <cassert>
#include <vector>
namespace luz {
template < typename T >
class FenwickTree {
usize n;
std::vector< T > vals;
T sum(usize k) const {
T result(0);
while (k > 0) {
result += vals[k];
k -= k & -k;
}
return result;
}
public:
FenwickTree() = default;
explicit FenwickTree(usize n): n(n), vals(n + 1, T()) {}
explicit FenwickTree(const std::vector< T > &as)
: n(as.size()),
vals(as.size() + 1, T()) {
for (usize i: rep(1, as.size() + 1)) {
vals[i] = as[i - 1];
}
for (usize i: rep(1, as.size() + 1)) {
usize j = i + (i & -i);
if (j <= as.size()) {
vals[j] += vals[i];
}
}
}
void add(usize k, const T &v) {
assert(k < n);
k++;
while (k <= n) {
vals[k] += v;
k += k & -k;
}
}
T sum(usize l, usize r) const {
assert(l <= r and r <= n);
return sum(r) - sum(l);
}
};
} // namespace luz
#line 2 "src/data-structure/fenwick-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/fenwick-tree.hpp"
#include <cassert>
#include <vector>
namespace luz {
template < typename T >
class FenwickTree {
usize n;
std::vector< T > vals;
T sum(usize k) const {
T result(0);
while (k > 0) {
result += vals[k];
k -= k & -k;
}
return result;
}
public:
FenwickTree() = default;
explicit FenwickTree(usize n): n(n), vals(n + 1, T()) {}
explicit FenwickTree(const std::vector< T > &as)
: n(as.size()),
vals(as.size() + 1, T()) {
for (usize i: rep(1, as.size() + 1)) {
vals[i] = as[i - 1];
}
for (usize i: rep(1, as.size() + 1)) {
usize j = i + (i & -i);
if (j <= as.size()) {
vals[j] += vals[i];
}
}
}
void add(usize k, const T &v) {
assert(k < n);
k++;
while (k <= n) {
vals[k] += v;
k += k & -k;
}
}
T sum(usize l, usize r) const {
assert(l <= r and r <= n);
return sum(r) - sum(l);
}
};
} // namespace luz