扫描线
思想
顾名思义,扫描线就是要模拟一根线,扫过整个图形。至于方向什么的自己根据喜好,这里选用从左往右的方式。
过程
朴素做法
首先我们看一下这个例子:

我们有三个矩形,分别用红、蓝、绿三色标注了出来。
他们相交的面积用其他的颜色标了出来。
我们所得到的信息只有矩形的左下端点和右上端点的坐标。也就是我们标红的这几个点:

然后我们可以画出一根线来,扫过这个多边形的所有面积。
这根线从最左边的边开始,每遇到一条边,就停下来计算之前扫到的面积,即为距上一条边的距离与扫描线落在图形上的长度之积,再加到之前的和上面。
用动画来做就是这样的:

但是这样做有一处需要注意的地方: 我们怎么才能知道每一次遇到一条边之后扫描线落在图像上的长度是多少 ?
如果我们每一次都去枚举、去找,我们程序的时间复杂度就达不到我们的要求了。
这就是扫描线算法的精髓之处。
线段树
分段
我们把 轴上的一段区间按照每一个存在的矩形的边的高度值分一下块:

我们只需要计算每一段所对应的在 轴上的长度就行了。
我们可以使用线段树这一强大的数据结构来帮助我们更快地进行区间修改。

标记
我们在遇到某个矩形的一条边的时候,我们需要看一下这两个东西:
- 它的长度;
- 他是起始边还是终止边。
如果是起始边的话,我们把他这条边所包含的所有区块都打上一个标记;如果是终止边的话,我们就把之前起始边打上的标记去掉。这样,只要有标记就是存在,不管有多少个;没有标记就是没有被覆盖,忽略不计。
所以,我们的线段树节点需要存储这个区段被标记的次数。同时,我们还需要存储基本的线段树信息,还有它的长度。
同时,我们用来存储矩形边的位置我们也需要改一下,使之能够存储这条边的上端点和下端点,还要标记这条边是起始边还是终止边。
最终我们使用动画模拟一下就是这个样子的:

例题
洛谷板子题:Luogu P5490 【模板】 扫描线:https://www.luogu.com.cn/problem/P5490
示例代码:Luogu P5490
__EOF__

本文链接:https://www.cnblogs.com/kaiserwilheim/p/16005425.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现