线段树相关问题 (引用 PKU POJ题目) 整理

1.RangeMinimum、Maximum Query问题(计算单调区间内出现最多(少)的次数)

对元素的起点做离散化,再把离散化后的位置作为线段树的[l, r),记录次数为t.

对输入区间a, b:

如果(a = b){很好处理},

如果(a = b – 1){分别计算a、b的次数,取大(小)的一项},

如果(a < b – 1){分别计算a、b的次数和线段树[a + 1, b – 1)的次数,取大(小)的一项};

pku3264-Balanced Lineup RMQ问题,求区间最大最小值的差

pku3368-Frequent values 转化为RMQ问题求解

2.排队插队问题(ID为i的人插到第j位,求最后序列)

先把插队顺序记录下来,然后倒序插入。用线段树记录已有的序列,计算当前人物的序号,注意重复插入的情况(重复插入则结果序列中只处理第一次出现位置)。 线段树记录[i, j)中的已插入的人数,所以每次插入都是insert(n, n + 1),Query函数和一般的find有所不同,传入的是偏移量,通过偏移量计算. 忘了哪道题了,反正有的。

3.矩形交求面积/周长

对纵坐标离散化并做扫描线。

如果求周长则记录原始y轴覆盖段数ocn,原始和当前覆盖区域长度ocl,cl,则ans+=abs(ocl-cl)+ocn*(x_now-x_pre)

如果计算面积只需要记录原始覆盖区域长度ocl,然后ans+=ocl*(x_now-x_pre)

pku1151-Atlantis 求矩形并的面积,用线段树+离散化+扫描线

pku1177-picture 求矩形并的周长,用线段树+离散化+扫描线

4.覆盖涂色查找颜色种数问题

把坐标离散化,注意边界如果是整数,右边+1取开区间,防止出现[(1,10),(1,3),(6,10)]输出为2的情况。

离散化可以放在线段树里,尽量不要用map离散化(效率问题),Insert到字节点时,先把父节点颜色插入子节点并重置父节点为未涂色。

查询时查询涂色子节点数量即可

pku2528-Mayor's posters 区间涂色问题,使用离散化+线段树

注意开线段树的大小,由于用数组模拟有空间浪费,注意不要RE,一般节点数可设为最大子节点数的8倍

注意离散化尽量用sort取不重复点而不是用map,用sort的效率大约是map的10倍

相关代码:

普通线段树[无离散化]:

矩形交[MAP离散化]:

涂色覆盖问题[[Sort数值离散化]:

二维线段树(这段不是自己写的Copy来的):

Last updated

Was this helpful?