Written by Johannes Kapfhammer.
Contents
A persistent data structure is a data structure that remembers it previous state for each modification. This allows to access any version of this data structure that interest us and execute a query on it.
Persistence is a technique that can be applied to most kinds of balanced trees, such as segment trees or treaps.
Persistent Segment Trees
Please read Advanced Segment Trees before continuing with this article.
Segment Tree is a data structure the can be turned into a persistent data structure efficiently (both in time and memory consumption). We want to avoid copying the complete tree before each modification, and we don’t want to loose the time behavior for answering range queries.
In fact, any change request in the Segment Tree leads to a change in the data of only O(logn) vertices along the path starting from the root. So if we store the Segment Tree using pointers (i.e. a vertex stores pointers to the left and the right child vertices), then when performing the modification query, we simply need to create new vertices instead of changing the available vertices. Vertices that are not affected by the modification query can still be used by pointing the pointers to the old vertices. Thus for a modification query new vertices will be created, including a new root vertex of the Segment Tree, and the entire previous version of the tree rooted at the old root vertex will remain unchanged.
Let’s give an example implementation for the simplest Segment Tree: when there is only a query asking for sums, and modification queries of single elements.
Note that this works on any kind of segment tree, including lazy ones.
Practice tasks:
Persistent Ropes
Similarly to a segment tree, this technique can be also applied to treaps.
Practice task: AROPE2.