Segment Tree Merging & Splitting
Segment tree merging and splitting are common techniques for segment trees, often used in scenarios where weight segment trees maintain multisets.
For example, if certain nodes on a tree have several operations, and it is necessary to pass information from child nodes to parent nodes from bottom to top, while the information at a single node can be conveniently maintained using a segment tree, the technique of segment tree merging can be applied to control the overall complexity.
Segment Tree Merging
Process
As the name suggests, segment tree merging refers to constructing a new segment tree where each node is the result of merging the corresponding nodes of two original segment trees. It is often used to maintain information on trees or graphs.
Obviously, we cannot actually build a full new segment tree every time, so we need to use the dynamic segment tree mentioned above.
The process of segment tree merging is essentially quite brute-force:
Assume the two segment trees are A and B, and we start merging recursively from node 1.
When recursing to a certain node, if the corresponding node in tree A or tree B is empty, directly return the corresponding node from the other tree. This utilizes the characteristic of dynamic segment trees.
If recursing to a leaf node, we merge the corresponding nodes from the two trees.
Finally, update the current node based on its child nodes and return.
Complexity of Segment Tree Merging
Obviously, for two full segment trees, the complexity of a single merge operation is \(O(n)\). However, in practice, weight segment trees are often used, and the total number of nodes in all segment trees that need to be merged is not much larger than the scale of \(n\). Moreover, merging generally does not repeatedly merge a certain segment tree, so the total number of nodes we ultimately add is roughly \(n\log n\) level. Thus, the total complexity of merging all segment trees is \(O(n\log n)\) level. Of course, in some cases, mergeable heaps may be a better choice.
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Example
luogu P4556 [Vani Has a Date] Rainy Tail / 【Template】Segment Tree Merging
Solution Idea
A template problem for segment tree merging. Use difference to convert tree modifications into single-point modifications, then perform a bottom-up dfs to merge segment trees and calculate the answer.
Reference Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | |
Segment Tree Splitting
Process
Segment tree splitting is essentially the inverse process of segment tree merging. Segment tree splitting is only applicable to ordered sequences; it is meaningless for unordered sequences and is commonly used in dynamic weight segment trees.
Note that when both splitting and merging exist, we must recycle nodes during merging to avoid potential node duplication issues during splitting.
Split the interval \([l,r]\) from a segment tree covering \([1,N]\) to form a new tree:
Start recursive splitting from node 1. If the node does not exist or the represented interval \([s,t]\) does not intersect with \([l,r]\), backtrack directly.
When \([s,t]\) intersects with \([l,r]\), a new node needs to be created.
When \([s,t]\) is completely contained within \([l,r]\), the current node needs to be directly attached under the new tree, and the old edge is disconnected.
Complexity of Segment Tree Splitting
It can be observed that at most \(\log n\) edges will be disconnected, so the time complexity of each split operation is \(O(\log n)\), equivalent to the complexity of a range query.
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Example
P5494 【Template】Segment Tree Splitting
Solution Idea
A template problem for segment tree splitting. Split the interval \([x,y]\).
-
Merge tree \(t\) into tree \(p\): a single merge operation.
-
Insert \(x\) copies of \(q\) into tree \(p\): single-point modification.
-
Query the number of elements in \([x,y]\): range sum.
-
Query the \(k\)-th smallest element.
Reference Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |
Exercises
- Luogu P4556 [Vani Has a Date] Rainy Tail / 【Template】Segment Tree Merging
- Luogu P5494 【Template】Segment Tree Splitting
- Luogu P1600 Love Running Every Day
- Luogu P4577 [FJOI2018] Leadership Group Problem
- Luogu P2824 [HEOI2016/TJOI2016] Sorting
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用