[You Have A new unallocated technology site] Yes, yes, it can be persistent !? ------ Persistent line segment tree popularity edition explanation, line segment popularity Edition
Recently, I ran into the data structure, so I decided to make it persistent and then found that ...... Not available at the first release ......
For a persistent data structure, the biggest feature is "query of historical versions", that is, you can return to the status before a certain modification and continue the operation; this "historical VERSION Query" produces other powerful operations.
Today, we will mainly explain how to use a persistent line segment tree. In fact, its other name "Chairman Tree" seems to be more known (Chairman % ).
Compared with a common line segment tree, the Chairman tree copies and modifies a chain during modification. This operation takes a long time.
Why ......
The data can be persisted. A simple idea is to create a line segment tree each time a modification is made. However, the time complexity and space complexity cannot be implemented.
Let's think about it. Every time a node is modified, only one node on the chain is modified, and other node information is not changed. Therefore, we create a new logn node including a new root for this modification. The other nodes are shared with the previous course tree. In this way, we can save the previous information and modify it.
For the Chairman Tree Insertion operation code, see the following. There are two versions: pointer and array:
Pointer version:
1 void insert (node * & a, node * B, int l, int r, int pos) 2 {3 a-> cnt = B-> cnt + 1; // cnt indicates the number of data in the tree. a indicates the new tree, B indicates the old tree, and 4 int mi = (l + r)> 1; 5 if (l = r) return; 6 if (pos <= mi) 7 {8 a-> ch [1] = B-> ch [1], a-> ch [0] = newnode (); 9 insert (a-> ch [0], B-> ch [0], l, mi, pos ); 10} 11 else 12 {13 a-> ch [0] = B-> ch [0], a-> ch [1] = newnode (); 14 insert (a-> ch [1], B-> ch [1], mi + 1, r, pos); 15} 16 a-> update (); 17}
Array version:
1 void insert (int rt1, int rt2, int l, int r, int pos) 2 {3 if (l = r) {cnt [rt1] = cnt [rt2] + 1; return;} // cnt indicates the number of data, and rt1 indicates the new tree, rt2 is the old tree 4 lc [rt1] = lc [rt2], rc [rt1] = rc [rt2]; 5 int mi = (l + r)> 1; 6 if (pos <= mi) lc [rt1] = ++ tot, insert (lc [rt1], lc [rt2], l, mi, pos ); 7 else rc [rt1] = ++ tot, insert (rc [rt1], rc [rt2], mi + 1, r, pos ); 8 cnt [rt1] = cnt [lc [rt1] + cnt [rc [rt1]; 9}
This part of the basic questions about cogs2554 (http://cogs.pro/cogs/problem/problem.php? Pid = 2554). This is an entry-level Question of the Chairman tree. If you are not familiar with it, you can use this question to get started.
Some may have noticed the cnt variable inserted in the code above, which is actually very useful: Next, we will consider using the Chairman tree for some more advanced operations: maintain the k (small) value of the static interval.
Why can the Chairman tree maintain this?
When querying a series of k (small) values, we build the Chair tree into a weight value line tree, and create a new version for each number inserted. At this time, it is not difficult to see that the Chairman tree has a range reduction:
For a certain interval [L, R] Insert the number of B after the number of The number of trees in the interval, minus [L, R] Insert the number of The number of A-1 after the number of The number of intervals,
The result is the number of weights in the range [a, B] in [L, R. In this way, the cnt variable is used for constant query, so that we can find the maximum k (small) value in a certain range.
In code implementation, we only need to input two nodes at the same time, and compare the relationship between the number of data ranges and the size of k to move it.
For the query operation code, see:
1 inline int query(int l,int r,int u,int v,int k) 2 { 3 node *a=root[u-1],*b=root[v]; 4 while(l<r) 5 { 6 int tmp=b->ch[0]->cnt-a->ch[0]->cnt,mi=(l+r)>>1; 7 if(tmp>=k)a=a->ch[0],b=b->ch[0],r=mi; 8 else a=a->ch[1],b=b->ch[1],k-=tmp,l=mi+1; 9 }10 return r;11 }
Note that the Chairman tree can only QueryStaticRange k (small) value.
Next, we will consider the dynamic interval k small value. If we want to modify the interval, a simple chair tree will no longer be implemented.
If you directly modify the original node, it will cause an unnamed running error (if you are interested, you can insert the code above to think about why ),
Space and time are unacceptable (we need to change all the trees behind it), but we can perform similar operations when building a tree, so what should the Chairman tree set?
The points on the chairman tree store the number of data in a weight range. We must maintain the number of data before we can subtract the number of weight line segments in a range.
Now there are modifications. There are two simple ways to maintain the modifications: O (1) query and O (n) Maintenance (sweep once ), O (n) query (field calculation) and O (1) maintenance.
These two methods are not very worrying, So we consider using the fast maintenance of the prefix and the tree array to solve this problem, that is, the so-called "tree number sets the Chairman tree"
In the figure, node c Represents the line segment tree of the corresponding interval. For example, the line segment Tree represented by 8th points is the line segment tree of the range [6th], and the points represent the line segment tree of the range [5, 6. The other points are the same.
During the modification, we can use a tree array to locate the maximum number of logstores to be modified, and save the changes. Query is similar.
You can use tree trees to set the Chair tree for common tree-based questions. Here are some exercises:
Bzoj3196 second forced Balance Tree http://www.lydsy.com/JudgeOnline/problem.php? Id = 3196
Bzoj1901 Zju2112 Dynamic Rankings (permission question) http://www.lydsy.com/JudgeOnline/problem.php? Id = 1901
Cogs 257 dynamic ranking system http://cogs.pro/cogs/problem/problem.php? Pid = 1, 257
My cogs257 code http://www.cnblogs.com/LadyLex/p/7275540.html
The above is not complete yet. What's more powerful is that the Chairman tree can not only maintain the series, but also operate and maintain the data on the tree.
In general, we have two ways to implement the tree in the Chairman's Tree:
One is to create a tree on the son Node Based on Father's Day. In this way, the array between a point and the root node can be maintained, and then the K value problem (or other problems) of a chain in the tree is derived from the LCA)
One is to build a tree in the dfs sequence and Euler sequence to solve the problem. In this way, the values of a subtree can be captured to generate other problems.
Why is the second method correct? If we follow the left range + 1 and right range-1, if the other end of a path is not in the chain, we will not count his answer (+ 1's time is too forward or backward, leading to no statistics). This is indeed clever ...... In this way, if the query point is located, we split the chain to be queried into [x. lca] and [y. fa [lca] And then query it. If we calculate the edge, we should calculate [x. lca] and [y. lca]. The answer at the lca is counted twice. Remember to subtract it. The query length of the vertex is as follows:
If there is any modification, you will not be able to use the first method above. You can only use the dfs sequence/Euler sequence to convert it into a sequence, and then use the tree number to set the Chairman tree. Insert into Stack point + 1 and out stack point-1. Delete stack entry point-1 and stack exit point + 1.
Some examples:
BZOJ3123 [Sdoi2013] forest http://www.lydsy.com/JudgeOnline/problem.php? Id = 3123
My question: http://www.cnblogs.com/LadyLex/p/7275793.html
BZOJ3551 [ONTAK2010] Peaks enhanced http://www.lydsy.com/JudgeOnline/problem.php? Id = 3551
Original Question No question surface (and bzoj3545 is the same, but bzoj3545 is the permission), you can take a look at my question surface (Force Amway wave) http://www.cnblogs.com/LadyLex/p/7275821.html
(In addition, in fact, the main knowledge point of the above question is not the chairman tree, it is the reconstruction tree 233 of kackar)
BZOJ3772 mental pollution (permission questions) http://www.lydsy.com/JudgeOnline/problem.php? Id = 3772
My question: http://www.cnblogs.com/LadyLex/p/7279150.html
In addition to the above basic operations, the Chairman tree can also deal with a bunch of problems, because this is a general explanation and I will not list the lazy cancer attacks 233.
The Chair tree is a powerful data structure. By creating a chain and sharing sub-nodes, you can not only record historical version values, but also support many other operations. I hope you will have some gains after reading this blog! :)
In addition, in the next few days, I will add a persistent balance tree (no-spin Treap), a persistent Trie tree, and a persistent query set ~