Templates -- Meow  1.1.4
A C++ template which is unable and also not allowed to compile to obj-file first.
SegmentTree.h
Go to the documentation of this file.
1 #ifndef dsa_SegmentTree_H__
2 #define dsa_SegmentTree_H__
3 
4 #include "../math/utility.h"
5 
6 #include <vector>
7 #include <algorithm>
8 
9 #include <cstdlib>
10 
11 namespace meow {
44 template<class Value>
45 class SegmentTree {
46 private:
47  struct Node {
48  Value value_;
49  Value offset_;
50  bool sameFlage_;
51  };
52  //
53  size_t size_;
54  std::vector<Node> nodes_;
55  //
56  void update(size_t index, size_t size, Value const& value, bool override) {
57  if (override) {
58  nodes_[index].value_ = value * size;
59  nodes_[index].offset_ = value;
60  nodes_[index].sameFlage_ = true;
61  }
62  else {
63  nodes_[index].value_ = nodes_[index].value_ + value * size;
64  nodes_[index].offset_ = nodes_[index].offset_ + value;
65  }
66  }
67  void update(size_t l, size_t r, size_t L, size_t R,
68  size_t index, Value const& value,
69  bool override) {
70  if (l == L && r == R) {
71  update(index, R - L + 1, value, override);
72  return ;
73  }
74  size_t mid = (L + R) / 2;
75  if (L < R) {
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;
82  }
83  if (r <= mid) {
84  update(l, r, L ,mid, index * 2 + 1, value, override);
85  }
86  else if (mid + 1 <= l) {
87  update(l, r, mid + 1,R, index*2 + 2, value, override);
88  }
89  else {
90  update(l, mid , L, mid , index * 2 + 1, value, override);
91  update( mid + 1, r, mid + 1, R, index * 2 + 2, value, override);
92  }
93  nodes_[index].value_ = (
94  (nodes_[index * 2 + 1].value_ | nodes_[index * 2 + 2].value_)
95  + nodes_[index].offset_
96  );
97  }
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;
105  else{
106  return ( query(l, mid , L, mid , index * 2 + 1)
107  | query( mid + 1, r, mid + 1, R, index * 2 + 2)
108  ) + off;
109  }
110  }
111  //
112  bool rangeCorrect(ssize_t* first, ssize_t* last) const {
113  if (*last < *first || *last < 0 || (ssize_t)size_ - 1 < *first)
114  return false;
115  *first = inRange((ssize_t)0, (ssize_t)size_ - 1, *first);
116  *last = inRange((ssize_t)0, (ssize_t)size_ - 1, *last );
117  return true;
118  }
119 public:
122  reset(1);
123  }
124 
126  SegmentTree(size_t size) {
127  reset(size);
128  }
129 
131  SegmentTree(SegmentTree const& tree2):
132  size_(tree2.size_), nodes_(tree2.nodes_) {
133  }
134 
139  size_ = b.size_;
140  nodes_ = b.nodes_;
141  return *this;
142  }
143 
147  size_t size() const {
148  return size_;
149  }
150 
154  void reset(size_t size){
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);
160  }
161 
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);
168  }
169 
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);
176  }
177 
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);
184  }
185 
188  return copyFrom(b);
189  }
190 };
191 
192 }
193 
194 #endif // dsa_SegmentTree_H__
SegmentTree()
constructor
Definition: SegmentTree.h:121
中文名 線段樹
Definition: SegmentTree.h:45
size_t size() const
回傳size
Definition: SegmentTree.h:147
void offset(ssize_t first, ssize_t last, Value const &delta)
將區間 [first,last] 全部都加上 delta
Definition: SegmentTree.h:181
SegmentTree & operator=(SegmentTree const &b)
same as copyFrom(b)
Definition: SegmentTree.h:187
SegmentTree copyFrom(SegmentTree const &b)
複製
Definition: SegmentTree.h:138
SegmentTree(SegmentTree const &tree2)
constructor, 並且複製資料
Definition: SegmentTree.h:131
SegmentTree(size_t size)
constructor, with size gived
Definition: SegmentTree.h:126
T inRange(T const &mn, T const &mx, T const &v)
std::min(mx,std::max(mn,v))
Definition: utility.h:51
void reset(size_t size)
將資料清空且設定維護範圍是 0~size-1
Definition: SegmentTree.h:154
Value query(ssize_t first, ssize_t last) const
回傳區間 [first,last] (邊界都含) 的區間值
Definition: SegmentTree.h:165