1 #ifndef dsa_SegmentTree_H__
2 #define dsa_SegmentTree_H__
4 #include "../math/utility.h"
54 std::vector<Node> nodes_;
56 void update(
size_t index,
size_t size, Value
const& value,
bool override) {
58 nodes_[index].value_ = value *
size;
59 nodes_[index].offset_ = value;
60 nodes_[index].sameFlage_ =
true;
63 nodes_[index].value_ = nodes_[index].value_ + value *
size;
64 nodes_[index].offset_ = nodes_[index].offset_ + value;
67 void update(
size_t l,
size_t r,
size_t L,
size_t R,
68 size_t index, Value
const& value,
70 if (l == L && r == R) {
71 update(index, R - L + 1, value,
override);
74 size_t mid = (L + R) / 2;
76 update(index * 2 + 1, mid - L + 1,
77 nodes_[index].offset_, nodes_[index].sameFlage_);
78 update(index * 2 + 2, R - mid,
79 nodes_[index].offset_, nodes_[index].sameFlage_);
80 nodes_[index].offset_ = Value(0);
81 nodes_[index].sameFlage_ =
false;
84 update(l, r, L ,mid, index * 2 + 1, value,
override);
86 else if (mid + 1 <= l) {
87 update(l, r, mid + 1,R, index*2 + 2, value,
override);
90 update(l, mid , L, mid , index * 2 + 1, value,
override);
91 update( mid + 1, r, mid + 1, R, index * 2 + 2, value,
override);
93 nodes_[index].value_ = (
94 (nodes_[index * 2 + 1].value_ | nodes_[index * 2 + 2].value_)
95 + nodes_[index].offset_
98 Value query(
size_t l,
size_t r,
size_t L,
size_t R,
size_t index) {
99 if (l == L && r == R)
return nodes_[index].value_;
100 Value off = nodes_[index].offset_ * (r - l + 1);
101 if (nodes_[index].sameFlage_)
return off;
102 size_t mid = (L + R) / 2;
103 if (r <= mid)
return query(l, r, L , mid, index * 2 + 1) + off;
104 else if(mid + 1 <= l)
return query(l, r, mid + 1, R, index * 2 + 2) + off;
106 return ( query(l, mid , L, mid , index * 2 + 1)
107 | query( mid + 1, r, mid + 1, R, index * 2 + 2)
112 bool rangeCorrect(ssize_t* first, ssize_t* last)
const {
113 if (*last < *first || *last < 0 || (ssize_t)size_ - 1 < *first)
115 *first =
inRange((ssize_t)0, (ssize_t)size_ - 1, *first);
116 *last =
inRange((ssize_t)0, (ssize_t)size_ - 1, *last );
132 size_(tree2.size_), nodes_(tree2.nodes_) {
155 size_ = std::max(size, (
size_t)1);
156 nodes_.resize(size * 4);
157 nodes_[0].sameFlage_ =
true;
158 nodes_[0].value_ = Value(0);
159 nodes_[0].offset_ = Value(0);
165 Value
query(ssize_t first, ssize_t last)
const {
166 if (rangeCorrect(&first, &last) ==
false)
return Value();
167 return ((
SegmentTree*)
this)->query(first, last, 0, size_ - 1, 0);
173 void override(ssize_t first, ssize_t last, Value
const& value) {
174 if (rangeCorrect(&first, &last) ==
false)
return ;
175 update(first, last, 0, size_ - 1, 0, value,
true);
181 void offset(ssize_t first, ssize_t last, Value
const& delta) {
182 if (rangeCorrect(&first, &last) ==
false) return ;
183 update(first, last, 0, size_ - 1, 0, delta,
false);
194 #endif // dsa_SegmentTree_H__
size_t size() const
回傳size
void offset(ssize_t first, ssize_t last, Value const &delta)
將區間 [first,last] 全部都加上 delta
SegmentTree & operator=(SegmentTree const &b)
same as copyFrom(b)
SegmentTree copyFrom(SegmentTree const &b)
複製
SegmentTree(SegmentTree const &tree2)
constructor, 並且複製資料
SegmentTree(size_t size)
constructor, with size gived
T inRange(T const &mn, T const &mx, T const &v)
std::min(mx,std::max(mn,v))
void reset(size_t size)
將資料清空且設定維護範圍是 0~size-1
Value query(ssize_t first, ssize_t last) const
回傳區間 [first,last] (邊界都含) 的區間值