📜  动态凸包|向现有凸包添加点(1)

📅  最后修改于: 2023-12-03 15:07:18.226000             🧑  作者: Mango

动态凸包 | 向现有凸包添加点

简介

动态凸包是指在不断向凸包中添加点的过程中维护当前的凸包状态,以便在需要时能够快速查询当前凸包状态中的最大值、最小值等信息。

向现有凸包中添加一个点需要对凸包进行一些修改,以保持凸包的性质。添加点的算法流程一般分为以下几步:

  1. 先找到新增点在凸包上的位置,也就是所谓的上凸壳和下凸壳中新增点的位置。
  2. 然后对凸壳进行修改,并更新凸包。
算法实现
1. 找到新增点在凸包上的位置

为了找到新增点在凸包上的位置,我们需要对凸壳进行遍历。区别上凸壳和下凸壳的方法是通过参数来实现的。我们取某个值 $x$,对于某个点 $p$:

  • 如果 $p$ 在点 $x$ 上方,则 $p$ 属于上凸壳。
  • 如果 $p$ 在点 $x$ 下方,则 $p$ 属于下凸壳。
  • 如果 $p$ 和 $x$ 重合,则 $p$ 可以在上凸壳或下凸壳中任选一条。

遍历凸壳时需要使用单调栈,这里不再赘述。

2. 修改凸壳并更新凸包

若新增点不在凸包上,我们需要对凸包进行修改。具体地,我们需要从两个方向对凸壳进行修改。

对于上凸壳,我们从栈顶开始弹出点,直到栈顶点到新增点之间两个点和新增点组成的线段为上升趋势为止,然后再将新增点加入栈顶。下凸壳的处理同理,只不过是寻找下降趋势。

此时,凸包的点序列已发生了变化,需要重新计算当前凸包。

算法复杂度

单次查询点是否在凸包上:$O(\log n)$。

单次添加点到凸包:$O(n)$。

总时间复杂度取决于添加点的数量和查询点是否在凸包上的次数,但是对于一个较小的数据集,该算法是足够快的。

参考资料

[1] Dynamic Convex Hull Learning Note (Part 1)

[2] 小曼大佬:【一种容易理解的】用单调栈维护动态凸包的详细步骤与套路(手写凸包可能没那么难了)