昨天开始接触线段树,感觉是很简单的数据结构,今天我发现我错了。
今天从早上纠结到现在,一直在看线段树有关的问题,其中POJ 2401(线段树+并归排序)还没有解决。发现线段树非常灵活,要掌握好也非常难。
在参考别人的基础上,做了POJ 2528。
现在总结一下要点:
1,离散化:题目中给出的海报长度范围时1~10000000,因此不可能建立一个如此大的线段树。而观察海报数量范围1~10000,相对来小就小的多了。于是考虑离散化方法:将所有海报的坐标(起始点和终点)排序,这些点最多也就有20000个,每张海报本来使用起始/终点坐标来表示的,现在可以使用起始/终点的“rank”作为映射来表示。
例如有三张海报:p1(1,100),p2(2,8) p3(3,6)
那么将所有起始/终点排序后存放在map:1,2,3,6,8,100。(注意可能存在重复的元素)
从而p1,p2和p3可以用(map[1],map[6]),(map[2],map[5)和(map[3],map[4])表示。于是可以建立一个[1,6]的线段树。
2,参考别人的做法,线段树每个节点增加一个域:c。
c>0表示此节点(某一段)被唯一的一张海报覆盖。
c=0表示未被任何海报覆盖或者被多于一张海报覆盖。
这样在所有海报张贴完毕后,搜索可现实海报种类时,只要遇到某个节点(某一段)的c是1,那么就不需要搜索子区域。 这也是线段树“对段操作的优雅性“的体现。不需要搜索到每一个点。