TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
range_queries::perSegTree Class Reference

Range query here is range sum, but the code can be modified to make different queries like range max or min. More...

Collaboration diagram for range_queries::perSegTree:
[legend]

Classes

class  Node
 

Public Member Functions

void construct (const std::vector< int64_t > &vec)
 Constructing the segment tree with the values in the passed vector. Returned root pointer is pushed in the pointers vector to have access to the original version if the segment tree is updated.
 
void update (const uint32_t &l, const uint32_t &r, const int64_t &value)
 Doing range update by passing the left and right indexes of the range as well as the value to be added.
 
int64_t query (const uint32_t &l, const uint32_t &r, const uint32_t &version)
 Querying the range from index l to index r, getting the sum of the elements whose index x satisfies l<=x<=r.
 
uint32_t size ()
 Getting the number of versions after updates so far which is equal to the size of the pointers vector.
 

Private Member Functions

std::shared_ptr< NodenewKid (std::shared_ptr< Node > const &curr)
 Creating a new node with the same values of curr node.
 
void lazy (const uint32_t &i, const uint32_t &j, std::shared_ptr< Node > const &curr)
 If there is some value to be propagated to the passed node, value is added to the node and the children of the node, if exist, are copied and the propagated value is also added to them.
 
std::shared_ptr< Nodeconstruct (const uint32_t &i, const uint32_t &j)
 Constructing the segment tree with the early passed vector. Every call creates a node to hold the sum of the given range, set its pointers to the children, and set its value to the sum of the children's values.
 
std::shared_ptr< Nodeupdate (const uint32_t &i, const uint32_t &j, const uint32_t &l, const uint32_t &r, const int64_t &value, std::shared_ptr< Node > const &curr)
 Doing range update, checking at every node if it has some value to be propagated. All nodes affected by the update are copied and propagation value is added to the leaf of them.
 
int64_t query (const uint32_t &i, const uint32_t &j, const uint32_t &l, const uint32_t &r, std::shared_ptr< Node > const &curr)
 Querying the range from index l to index r, checking at every node if it has some value to be propagated. Current node's value is returned if its range is completely inside the wanted range, else 0 is returned.
 

Private Attributes

uint32_t n = 0
 
std::vector< std::shared_ptr< Node > > ptrs {}
 number of elements/leaf nodes in the segment tree
 
std::vector< int64_t > vec {}
 

Detailed Description

Range query here is range sum, but the code can be modified to make different queries like range max or min.

Definition at line 39 of file persistent_seg_tree_lazy_prop.cpp.

Member Function Documentation

◆ construct() [1/2]

void range_queries::perSegTree::construct ( const std::vector< int64_t > & vec)
inline

Constructing the segment tree with the values in the passed vector. Returned root pointer is pushed in the pointers vector to have access to the original version if the segment tree is updated.

public methods that can be used directly from outside the class. They call the private functions that do all the work

Parameters
vecvector whose values will be used to build the segment tree
Returns
void

Definition at line 197 of file persistent_seg_tree_lazy_prop.cpp.

200 {
201 if (vec.empty()) {
202 return;
203 }
204 n = vec.size();
205 this->vec = vec;
206 auto root = construct(0, n - 1);
207 ptrs.push_back(root);
208 }
std::vector< std::shared_ptr< Node > > ptrs
number of elements/leaf nodes in the segment tree
std::shared_ptr< Node > construct(const uint32_t &i, const uint32_t &j)
Constructing the segment tree with the early passed vector. Every call creates a node to hold the sum...

◆ construct() [2/2]

std::shared_ptr< Node > range_queries::perSegTree::construct ( const uint32_t & i,
const uint32_t & j )
inlineprivate

Constructing the segment tree with the early passed vector. Every call creates a node to hold the sum of the given range, set its pointers to the children, and set its value to the sum of the children's values.

Parameters
ithe left index of the range that the created node holds its sum
jthe right index of the range that the created node holds its sum
Returns
pointer to the newly created node

Definition at line 106 of file persistent_seg_tree_lazy_prop.cpp.

106 {
107 auto newNode = std::make_shared<Node>(Node());
108 if (i == j) {
109 newNode->val = vec[i];
110 } else {
111 uint32_t mid = i + (j - i) / 2;
112 auto leftt = construct(i, mid);
113 auto right = construct(mid + 1, j);
114 newNode->val = leftt->val + right->val;
115 newNode->left = leftt;
116 newNode->right = right;
117 }
118 return newNode;
119 }

◆ lazy()

void range_queries::perSegTree::lazy ( const uint32_t & i,
const uint32_t & j,
std::shared_ptr< Node > const & curr )
inlineprivate

If there is some value to be propagated to the passed node, value is added to the node and the children of the node, if exist, are copied and the propagated value is also added to them.

Parameters
ithe left index of the range that the passed node holds its sum
jthe right index of the range that the passed node holds its sum
currpointer to the node to be propagated
Returns
void

Definition at line 83 of file persistent_seg_tree_lazy_prop.cpp.

84 {
85 if (!curr->prop) {
86 return;
87 }
88 curr->val += (j - i + 1) * curr->prop;
89 if (i != j) {
90 curr->left = newKid(curr->left);
91 curr->right = newKid(curr->right);
92 curr->left->prop += curr->prop;
93 curr->right->prop += curr->prop;
94 }
95 curr->prop = 0;
96 }
std::shared_ptr< Node > newKid(std::shared_ptr< Node > const &curr)
Creating a new node with the same values of curr node.

◆ newKid()

std::shared_ptr< Node > range_queries::perSegTree::newKid ( std::shared_ptr< Node > const & curr)
inlineprivate

Creating a new node with the same values of curr node.

values of the leaf nodes that the segment tree will be constructed with

Parameters
currnode that would be copied
Returns
the new node

Definition at line 65 of file persistent_seg_tree_lazy_prop.cpp.

65 {
66 auto newNode = std::make_shared<Node>(Node());
67 newNode->left = curr->left;
68 newNode->right = curr->right;
69 newNode->prop = curr->prop;
70 newNode->val = curr->val;
71 return newNode;
72 }

◆ query() [1/2]

int64_t range_queries::perSegTree::query ( const uint32_t & i,
const uint32_t & j,
const uint32_t & l,
const uint32_t & r,
std::shared_ptr< Node > const & curr )
inlineprivate

Querying the range from index l to index r, checking at every node if it has some value to be propagated. Current node's value is returned if its range is completely inside the wanted range, else 0 is returned.

Parameters
ithe left index of the range that the passed node holds its sum
jthe right index of the range that the passed node holds its sum
lthe left index of the range whose sum should be returned as a result
rthe right index of the range whose sum should be returned as a result
currpointer to the current node, which has value = the sum of elements whose index x satisfies i<=x<=j
Returns
sum of elements whose index x satisfies l<=x<=r

Definition at line 171 of file persistent_seg_tree_lazy_prop.cpp.

172 {
173 lazy(i, j, curr);
174 if (j < l || r < i) {
175 return 0;
176 }
177 if (i >= l && j <= r) {
178 return curr->val;
179 }
180 uint32_t mid = i + (j - i) / 2;
181 return query(i, mid, l, r, curr->left) +
182 query(mid + 1, j, l, r, curr->right);
183 }
void lazy(const uint32_t &i, const uint32_t &j, std::shared_ptr< Node > const &curr)
If there is some value to be propagated to the passed node, value is added to the node and the childr...
int64_t query(const uint32_t &i, const uint32_t &j, const uint32_t &l, const uint32_t &r, std::shared_ptr< Node > const &curr)
Querying the range from index l to index r, checking at every node if it has some value to be propaga...

◆ query() [2/2]

int64_t range_queries::perSegTree::query ( const uint32_t & l,
const uint32_t & r,
const uint32_t & version )
inline

Querying the range from index l to index r, getting the sum of the elements whose index x satisfies l<=x<=r.

Parameters
lthe left index of the range whose sum should be returned as a result
rthe right index of the range whose sum should be returned as a result
versionthe version to query on. If equals to 0, the original segment tree will be queried
Returns
sum of elements whose index x satisfies l<=x<=r

Definition at line 241 of file persistent_seg_tree_lazy_prop.cpp.

246 {
247 return query(0, n - 1, l, r, ptrs[version]);
248 }

◆ size()

uint32_t range_queries::perSegTree::size ( )
inline

Getting the number of versions after updates so far which is equal to the size of the pointers vector.

Returns
the number of versions

Definition at line 255 of file persistent_seg_tree_lazy_prop.cpp.

258 {
259 return ptrs.size();
260 }

◆ update() [1/2]

std::shared_ptr< Node > range_queries::perSegTree::update ( const uint32_t & i,
const uint32_t & j,
const uint32_t & l,
const uint32_t & r,
const int64_t & value,
std::shared_ptr< Node > const & curr )
inlineprivate

Doing range update, checking at every node if it has some value to be propagated. All nodes affected by the update are copied and propagation value is added to the leaf of them.

Parameters
ithe left index of the range that the passed node holds its sum
jthe right index of the range that the passed node holds its sum
lthe left index of the range to be updated
rthe right index of the range to be updated
valuethe value to be added to every element whose index x satisfies l<=x<=r
currpointer to the current node, which has value = the sum of elements whose index x satisfies i<=x<=j
Returns
pointer to the current newly created node

Definition at line 135 of file persistent_seg_tree_lazy_prop.cpp.

138 {
139 lazy(i, j, curr);
140 if (i >= l && j <= r) {
141 std::shared_ptr<Node> newNode = newKid(curr);
142 newNode->prop += value;
143 lazy(i, j, newNode);
144 return newNode;
145 }
146 if (i > r || j < l) {
147 return curr;
148 }
149 auto newNode = std::make_shared<Node>(Node());
150 uint32_t mid = i + (j - i) / 2;
151 newNode->left = update(i, mid, l, r, value, curr->left);
152 newNode->right = update(mid + 1, j, l, r, value, curr->right);
153 newNode->val = newNode->left->val + newNode->right->val;
154 return newNode;
155 }
std::shared_ptr< Node > update(const uint32_t &i, const uint32_t &j, const uint32_t &l, const uint32_t &r, const int64_t &value, std::shared_ptr< Node > const &curr)
Doing range update, checking at every node if it has some value to be propagated. All nodes affected ...

◆ update() [2/2]

void range_queries::perSegTree::update ( const uint32_t & l,
const uint32_t & r,
const int64_t & value )
inline

Doing range update by passing the left and right indexes of the range as well as the value to be added.

Parameters
lthe left index of the range to be updated
rthe right index of the range to be updated
valuethe value to be added to every element whose index x satisfies l<=x<=r
Returns
void

Definition at line 219 of file persistent_seg_tree_lazy_prop.cpp.

223 {
224 ptrs.push_back(update(
225 0, n - 1, l, r, value,
226 ptrs[ptrs.size() -
227 1])); // saving the root pointer to the new segment tree
228 }

Member Data Documentation

◆ n

uint32_t range_queries::perSegTree::n = 0
private

Definition at line 52 of file persistent_seg_tree_lazy_prop.cpp.

◆ ptrs

std::vector<std::shared_ptr<Node> > range_queries::perSegTree::ptrs {}
private

number of elements/leaf nodes in the segment tree

Definition at line 54 of file persistent_seg_tree_lazy_prop.cpp.

54{};

◆ vec

std::vector<int64_t> range_queries::perSegTree::vec {}
private

ptrs[i] holds a root pointer to the segment tree after the ith update. ptrs[0] holds a root pointer to the segment tree before any updates

Definition at line 57 of file persistent_seg_tree_lazy_prop.cpp.

57{};

The documentation for this class was generated from the following file: