Personal perception interval merging is one of the most deformed and difficult applications of segment trees.
(The following is an example of finding the longest continuous 1 in the 01 sequence)
tree[cur].left represents the length of the continuous segment starting at the left end of the interval tree[cur].right represents the right tree[cur].all represents the longest continuous segment in the interval.
Through the combination of these three variables, there are generally four values for each interval for us to use.
1 tree[cur].left represents the length of a continuous segment (left continuous segment) starting at the left end of the interval.
2 tree[cur].right represents the length of a continuous segment (right continuous segment) that ends at the right end of the interval.
3 tree[2*cur].right+tree[2*cur+1].left represents the length of the continuous segment containing the midpoint of the interval. This is an implicit value (the middle continuous segment).
4 tree[cur].all represents the longest continuous segment in the interval, and its value should not only be selected from the longest continuous segment of the left and right subnodes, but also consider the middle continuous segment of the interval, namely tree [cur]. all = max (tree [2 * cur]. right + tree [2 * cur + 1]. left, Max (tree [2 * cur]. all, tree [2 * cur + 1]).
For the value of tree[cur].all, it can be understood that if two subintervals merge to produce a new continuous segment, it must be the value of tree[2*cur].right+tree[2*cur+1].left, that is, if there is no middle continuous segment, the longest continuous segment in the two subintervals can only be selected.
The key to interval merging lies in the construction of pushup functions as detailed in the code annotations (for example, finding the longest continuous 1 in the 01 sequence)
void pushup(int cur) { tree[cur].left=tree[2*cur].left;//The left endpoint of the left interval of the current interval must also be the left endpoint of the current interval, so the longest continuous 1 length starting from the left endpoint of the current interval must contain the corresponding value of its left interval. if(tree[cur].left==tree[2*cur].r-tree[2*cur].l+1) tree[cur].left+=tree[2*cur+1].left;//Judge again whether these consecutive 1's have run through the whole left interval and are connected with the interval. If so, the corresponding value of the right child must be added (if the corresponding interval of the right child is all 1, then the current interval will be all 1, which is also very possible). /* For example, [1,8] interval (1111) (1111) When not pushup tree[2*cur].left==4,tree[2*cur].right==4,tree[2*cur].all==4 tree[2*cur+1].left==2,tree[2*cur+1].right==1,tree[2*cur+1].all==2 After tree[cur].left=tree[2*cur].left = tree [cur]. left = 4, but obviously the length of the left continuous segment of the current interval also needs to be calculated as part of the right interval. So to execute tree[cur].left+=tree[2*cur+1].left and then tree[cur].left==6 is the correct result. */ tree[cur].right=tree[2*cur+1].right;//The processing of the right continuous segment is the same as above. if(tree[cur].right==tree[2*cur+1].r-tree[2*cur+1].l+1) tree[cur].right+=tree[2*cur].right; tree[cur].all=max(tree[2*cur].right+tree[2*cur+1].left,max(tree[2*cur].all,tree[2*cur+1].all)); //Obviously, the longest continuous segment of the current interval should be maximized from the longest continuous segment of the left and right intervals, but is that enough? //The value of tree[cur].all should not only choose the maximum from the longest continuous segment of the left and right subintervals, but also consider the implicit "middle continuous segment" of the interval. /* For example, [1,12] interval (11,10,1) and (11,10,11) When not pushup tree[2*cur].left==3,tree[2*cur].right==2,tree[2*cur].all==3 tree[2*cur+1].left==2,tree[2*cur+1].right==3,tree[2*cur+1].all==3 If we only consider maximizing the longest continuous segment of the left and right intervals, we execute tree[cur].all=max(tree[2*cur].all,tree[2*cur+1].all) followed by tree[cur].all==3. But apparently there are four consecutive ones missing out. */ return; }
Here is a summary of some of the types of questions that have been done.
1. Seek a left-most blank space that meets the criteria.
2. Find the length of the continuous segment where an element is located (or the left and right endpoints). hdu1540
3. Ask for the starting position of a continuous segment HDU 2871
Application of 4-interval merging in circumference calculation of scanning line hdu1828
Combining 5 interval merging with XOR operation and finding the length of the longest continuous segment in the whole interval
6. Seek the longest continuous ascending sequence of intervals hdu3308
7. Seek the largest subparagraph and uva1400 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *