1

I am trying to implement Persistent Segment Tree. The queries are of 2 types: 1 and 2.

1 ind val : update the value at ind to val in the array

2 k l r : find the sum of elements from index l to r after the kth update operation.

I have implemented the update and query functions properly and they are working fine on an array. But the problem arises when I am forming different versions. Basically this is my part of code

while (q--) {
        cin >> type;
        if (type == 1) {
            cin >> ind >> val;

            node *t = new node;
            *t = *ver[size - 1];
            update(t, ind, val);
            ver.pb(t);
            size++;

        }

    }

cout << query(ver[0], 0, 1) << ' ' << query(ver[1], 0, 1) << query(ver[2], 0, 1);

Now the problem is it is also changing the parameters for the all the node is the array. That means after 3 updates all the versions are storing the latest tree. This is probably because I am not properly allocating the new pointer. The changes made to the new pointer are getting reflected in all the pointers in the array

For example if I give this input

5
1 2 3 4 5
2
1 1 10
1 0 5

where 5 is the number of elements in the array and following is the array. Then there is q, number of queries and then all the queries. After carrying out the update the value of query function called for (l, r) = (0, 1) for all the 3 versions are 15. But it should be 3, 11, 15. What am I doing wrong

Nikhil Rathore
  • 170
  • 2
  • 14

1 Answers1

1

So let's say we have some simple segment tree like this:

enter image description here

For Persistant segment tree, during update we generate new nodes for all changed nodes and replace pointers to new nodes where needed, so let's say we update node 4, then we get a persistent segment tree like this (new nodes marked with *):

enter image description here

And all you're doing is replacing the root and copying all data so you get something like this:

enter image description here

Photon
  • 2,717
  • 1
  • 18
  • 22
  • Okay so first I copied all the data and structure looks like the 2nd image. But then I am calling the update option for this newly formed node. So it should update the tree according to the change. The problem is not that I am not able to construct every version. The problem is all the nodes are changing. So probably my way of copying of the node is not proper. Whatever changes I made to a new node should not affect the previous nodes. How should I do that – Nikhil Rathore Mar 23 '19 at 07:10
  • Well you probably have some copying error so you can try making the tree without pointers like here: https://github.com/Photon-LT/Algorithms-and-Data-Structures/blob/master/Data%20Structures/Segment%20tree/Persistent%20Segment%20Tree%20sum.cpp – Photon Mar 23 '19 at 07:38
  • Surely I can do that but I want to know the problem that is occuring here. What is the correct way of making a copy of another object. – Nikhil Rathore Mar 23 '19 at 09:48
  • Well if you do node* a = b; and b is another node*, all you`re doing is making another pointer to same object, so correct way of copying one node* to other would be something like node* a = new node(); a.data = b.data; As for segment tree you need to keep doing this during updates, so when update query comes in you: 1. Create new root. 2. copy from old root to new one. 3. While updating if you need to go to some node (like from [1,2]* to [1]) you need to create new node([1]*) copy the data from original node [1] and change pointer of node[1,2]* so it points to correct new version – Photon Mar 23 '19 at 10:22