forked from google/or-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinary_indexed_tree.h
71 lines (60 loc) · 2.19 KB
/
binary_indexed_tree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Copyright 2010-2024 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OR_TOOLS_ALGORITHMS_BINARY_INDEXED_TREE_H_
#define OR_TOOLS_ALGORITHMS_BINARY_INDEXED_TREE_H_
#include <vector>
#include "absl/log/check.h"
namespace operations_research {
// A binary indexed tree is a data structure that represents an array of
// numbers and supports two operations:
// 1) add a number to i-th element of the array.
// 2) find the sum of a prefix of the array (elements from 0-th to j-th).
// See http://en.wikipedia.org/wiki/Fenwick_tree.
template <typename T>
class BinaryIndexedTree {
public:
// Initializes the storage for a binary indexed tree of a given size. The
// tree contains all zeros initially.
explicit BinaryIndexedTree(int n) : tree_(n + 1, 0) {}
// Adds value to index-th number.
void AddItem(int index, T value) {
DCHECK_GE(index, 0);
DCHECK_LT(index, tree_.size() - 1);
// Internal indices of BinaryIndexedTree are 1 based.
++index;
while (index < tree_.size()) {
tree_[index] += value;
index += index & -index;
}
}
// Finds the sum of a prefix [0, index]. Passing index == -1 is allowed,
// will return 0 in that case.
T GetPrefixSum(int index) const {
DCHECK_GE(index, -1);
DCHECK_LT(index + 1, tree_.size());
// Internal indices of BinaryIndexedTree are 1 based.
++index;
T prefix_sum = 0;
while (index > 0) {
prefix_sum += tree_[index];
index -= index & -index;
}
return prefix_sum;
}
// Returns the size of the tree.
int size() const { return tree_.size() - 1; }
private:
std::vector<T> tree_;
};
} // namespace operations_research
#endif // OR_TOOLS_ALGORITHMS_BINARY_INDEXED_TREE_H_