mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
Updated
This commit is contained in:
parent
558b74f1dd
commit
b999e1848f
@ -5,8 +5,7 @@
|
||||
// query -> range sum
|
||||
class perSegTree {
|
||||
private:
|
||||
class Node {
|
||||
public:
|
||||
struct Node {
|
||||
Node *left;
|
||||
Node *right;
|
||||
int64_t val, prop;
|
||||
@ -20,8 +19,10 @@ private:
|
||||
|
||||
int n; // number of elements in the segment tree
|
||||
std::vector<Node *> ptrs; // ptrs[i] holds a root pointer to the segment tree after the ith update
|
||||
std::vector<int> vec;
|
||||
|
||||
Node *newKid(Node *curr) {
|
||||
Node *newNode = new Node();
|
||||
Node *newNode = new Node;
|
||||
*newNode = *curr;
|
||||
return newNode;
|
||||
}
|
||||
@ -41,14 +42,14 @@ private:
|
||||
curr->prop = 0;
|
||||
}
|
||||
|
||||
void construct(int i, int j, std::vector<int> &vec, Node *&curr) {
|
||||
curr = new Node();
|
||||
void construct(int i, int j, Node *&curr) {
|
||||
curr = new Node;
|
||||
if (i == j) {
|
||||
curr->val = vec[i];
|
||||
} else {
|
||||
int mid = i + (j - i) / 2;
|
||||
construct(i, mid, vec, curr->left);
|
||||
construct(mid + 1, j, vec, curr->right);
|
||||
construct(i, mid, curr->left);
|
||||
construct(mid + 1, j, curr->right);
|
||||
curr->val = curr->left->val + curr->right->val;
|
||||
}
|
||||
}
|
||||
@ -65,7 +66,7 @@ private:
|
||||
if (i > r || j < l) {
|
||||
return curr;
|
||||
}
|
||||
Node *newNode = new Node();
|
||||
Node *newNode = new Node;
|
||||
int mid = i + (j - i) / 2;
|
||||
newNode->left = update(i, mid, l, r, value, curr->left);
|
||||
newNode->right = update(mid + 1, j, l, r, value, curr->right);
|
||||
@ -86,7 +87,7 @@ private:
|
||||
return query(i, mid, l, r, curr->left) + query(mid + 1, j, l, r, curr->right);
|
||||
}
|
||||
|
||||
void clear(Node *&curr, int version) {
|
||||
/*void clear(Node *&curr, int version) {
|
||||
if (!curr || curr->version != version) {
|
||||
return;
|
||||
}
|
||||
@ -94,48 +95,47 @@ private:
|
||||
clear(curr->right, version);
|
||||
delete curr;
|
||||
}
|
||||
|
||||
*/ // for deallocation , version is passed to delete the current node iff its version = passed version
|
||||
// that is, this node was created when the segment tree, whose version = this node's version, was created
|
||||
// this is done to delete the segment trees top down version by version
|
||||
public:
|
||||
perSegTree() {
|
||||
n = 0;
|
||||
}
|
||||
|
||||
void construct(std::vector<int> &vec) // the segment tree will be built from the values in "vec", "vec" is 0 indexed
|
||||
void construct(std::vector<int> vec) // the segment tree will be built from the values in "vec", "vec" is 0 indexed
|
||||
{
|
||||
if (vec.empty()) {
|
||||
return;
|
||||
}
|
||||
n = vec.size();
|
||||
this->vec = vec;
|
||||
Node *root = nullptr;
|
||||
construct(0, n - 1, vec, root);
|
||||
construct(0, n - 1, root);
|
||||
ptrs.push_back(root);
|
||||
}
|
||||
|
||||
void update(int l, int r,
|
||||
int value) // all elements from index "l" to index "r" would by updated by "value", "l" and "r" are 0 indexed
|
||||
void update(int l, int r, int value) // all elements from index "l" to index "r" would by updated by "value", "l" and "r" are 0 indexed
|
||||
{
|
||||
ptrs.push_back(update(0, n - 1, l, r, value,
|
||||
ptrs[ptrs.size() - 1])); // saving the root pointer to the new segment tree
|
||||
}
|
||||
|
||||
int64_t query(int l, int r,
|
||||
int version) // querying the range from "l" to "r" in a segment tree after "version" updates, "l" and "r" are 0 indexed
|
||||
int64_t query(int l, int r, int version) // querying the range from "l" to "r" in a segment tree after "version" updates, "l" and "r" are 0 indexed
|
||||
{
|
||||
return query(0, n - 1, l, r, ptrs[version]);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (int i = (int) ptrs.size() - 1; i >= 0; --i) {
|
||||
clear(ptrs[i],
|
||||
i); // every segment tree clears its nodes (nodes that were created when this segment tree was created)
|
||||
/*void clear() {
|
||||
for (int i = static_cast<int>(ptrs.size()) - 1; i >= 0; --i) {
|
||||
clear(ptrs[i],i); // every segment tree clears its nodes (nodes that were created when this segment tree was created)
|
||||
}
|
||||
while (!ptrs.empty()) {
|
||||
ptrs.pop_back();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
int
|
||||
size() // returns the number of segment trees (versions) , the number of updates done so far = returned value - 1 ,because one of the trees is the original segment tree
|
||||
int size() // returns the number of segment trees (versions) , the number of updates done so far = returned value - 1 ,because one of the trees is the original segment tree
|
||||
{
|
||||
return ptrs.size();
|
||||
}
|
||||
@ -178,5 +178,4 @@ int main() {
|
||||
std::cout << "Number of segment trees (versions) now = " << tree.size() << '\n';
|
||||
std::cout << "Querying range sum on version 0 from index 3 to 5 = 11-2+7 = " << tree.query(3, 5, 0) << '\n';
|
||||
std::cout << "Querying range sum on version 1 from index 3 to 5 = 4-9+0 = " << tree.query(3, 5, 1) << '\n';
|
||||
tree.clear();
|
||||
}
|
Loading…
Reference in New Issue
Block a user