Line segment tree interval merge summary

Personally, I feel that interval merging is one of the most deformed and difficult to understand in various applications of line 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 from the left endpoint 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 the continuous segment starting from the left endpoint of the interval (left continuous segment)

2 tree[cur].right represents the length of the continuous segment ending at the right endpoint of the interval (right continuous segment)

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 child nodes, but also the middle continuous segment of the interval, that is, tree[cur].all=max( tree[2*cur].right+tree[2*cur+1].left,max(tree[2*cur].all,tree[2*cur+1].all));

   For the value of tree[cur].all, it can be understood that if a new continuous segment is generated after the two subintervals are merged, it must be the value of tree[2*cur].right+tree[2*cur+1].left, namely If there is no intermediate continuous segment, it can only be selected in the longest continuous segment of the two subintervals.

 

The key to interval merging lies in the construction of the pushup function. For details, please refer to the code comments (take the longest continuous 1 in the 01 sequence as an example)

void pushup(int cur)
{
    tree[cur].left=tree[2*cur].left;//当前区间的左区间的左端点肯定也是当前区间的左端点 所以以当前区间的左端点为起点的最长连续1长度肯定包含其左区间的对应值 这一部分值先记下来
    if(tree[cur].left==tree[2*cur].r-tree[2*cur].l+1) tree[cur].left+=tree[2*cur+1].left;//再判断一下当前这些连续的1是不是已经贯穿了整个左区间 和有区间接轨 如果是的话 必须把右孩子的对应值也加上(如果右孩子对应区间全为1 那么当前区间也会全为1 这种情况也是很有可能的)

    /*
    比如[1,8]区间 (1 1 1 1) (1 1 0 1)
    在未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

    执行完tree[cur].left=tree[2*cur].left后tree[cur].left==4 但显然以当前区间的左连续段的长度还需要算上右区间中的一部分
    所以要执行tree[cur].left+=tree[2*cur+1].left 然后tree[cur].left==6即为正确结果
    */

    tree[cur].right=tree[2*cur+1].right;//右连续段的处理同上
    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));
    //显然当前区间最长连续段要从左右区间的最长连续段取最大值 但这样就足够了吗?
    //tree[cur].all的值不止要从左右子区间的最长连续段中择最大 还要考虑该区间隐含的"中间连续段"
    /*
    比如[1,12]区间 (1 1 1 0 1 1) (1 1 0 1 1 1)
    在未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
    只考虑从左右区间的最长连续段取最大值的话 即执行tree[cur].all=max(tree[2*cur].all,tree[2*cur+1].all)之后tree[cur].all==3
    但显然中间有四个连续的1被漏掉了
    */
    return;
}

 

 

 

The following is a summary of some of the types of questions that have been done

1 Find the leftmost blank space that satisfies the condition poj3667

2 Find the length of the continuous segment where an element is located (you can also find the left and right endpoints) hdu1540

3 Find the starting position of a continuous segment hdu2871

4 The application of interval merging in finding perimeter of scan line hdu1828

5 Interval merging and XOR operation and finding the length of the longest continuous segment in the entire interval hdu3911 hdu3397

6 Find the longest continuous rising sequence hdu3308

7 Find the largest subsection and uva1400

 

 

to be continued

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325474199&siteId=291194637