Persistence Made Simple - Tutorial

Very nice ^^

Another problem

Thanks! See my other answer for lazy propagation above link

Awesome! I mean how can anyone spend lots of time writing these blogs just for the sake of others … great tutorial …

Well I was trying question on spoj mentioned above …

I am using same approach as explained above but not able to implement it … Can someone help me or if possible send me the link of solution to this problem so that it might help me … Thanks in advance!

1 Like

hey @hikarico I’m trying to understand your approach( in June17 CLONEME question. You have used persistent hash tree. but I’m not getting your approach from line 133. If the left or right any of them are not equal then we are searching for leftmost or rightmost, but it could be in between also…? did I misunderstand something here?

I dont have enough karma points to reply to your comment on original post.

1 Like

Let’s say I want to compare if array [1, 2, 2, 3, 4] is similar to [1, 2, 3, 3, 4]. My trees represent hashing of frequency tables {1:1, 2:2, 3:1, 4:1} and {1:1, 2:1, 3:2, 4:1}

 Tree 1             Tree 2
  [1, 2, 1, 1]        [1, 1, 2, 1]
    /      \            /      \
 [1, 2]  [1, 1]      [1, 1]  [2, 1]
  /  \    /  \        /  \    /  \
...                  ...

Look at second layer, there’s a special case where both left and right have mismatch, but the result is still “similar”. This can be solved by comparing rightmost and leftmost in both trees.

You’ll need to do LCA with jumping pointers. You have tree[a] contain all nodes from root to a (you can use range sum). Then to find out if c is in the path from a to b, you check if query(c, tree[a]) + query(c, tree[b]) - query(c, tree[parent(LCA(a, b))]) == 1 with principle of inclusion-exclusion :slight_smile:

Thanks mate, It is clear now. I’m gonna write a small post on persistent hash tree.

1 Like

Great ! thanks :slight_smile:

So well explained.

nice tutorial

1 Like

So when we are building PST(initially) we always build a copy of original SegT ? (As we are doing in build() function by calling newleaf() and newparent())

By convention yes, if you have an initial array. But if tree is empty at the start, you can make also do without build by assigning tree as null (0) at the start, and do point updates one by one (e.g. path-to-root problems)

and st[] here stores the sum of elements in pre-order fashion, not conventional parent to child [2*i,2*i+1] way, does it make things easy ?

KQUERY can’t be solved using persistent segment tree? I am getting TLE.


Has anyone solved [DQUERY][1] or [KQUERY][2] using persistent segment tree?

I have done these using segment tree and offline approach.

Edit: done both using persistent segment tree also.

hey i have done DQUERY using MO’s algorithm,but i am unable to solve that using persistent segment tree.can you please share your code?

SPOJ set the time limit really strict for KQUERY, they specifically wanted offline solution for that with a faster data structure (e.g. fenwick). That’s why they created KQUERYO as a separate online problem.


I assume you did DQUERY by sorting queries by right endpoint? Then you can do the same technique using persistent tree. Same technique, but during build you store the tree at index R as tree[R]. You can now solve queries online, just call tree[R].range_query(L, R)

For KQUERY, the TLE is strict there so only offline works (cuz SPOJ)… but there’s an online counterpart KQUERYO, you can solve that with persistent

best tutorial for leaning all about persistent segment tree.