动态凸壳技巧

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态凸壳技巧相关的知识,希望对你有一定的参考价值。

我在空闲时间阅读有趣的算法,我刚刚发现了凸壳技巧算法,我们可以用它来计算给定x坐标平面中几条线的最大值。我找到了这篇文章:

http://wcipeg.com/wiki/Convex_hull_trick

作者在这里说,该算法的动态版本以对数时间运行,但没有证据。当我们插入一条线时,我们测试了他的一些邻居,但我不明白当我们可以通过这样的插入测试所有O(log N)线时它是怎么可能是N。这是正确的还是我错过了什么? 更新:这个问题已经回答了,有趣的是下面的其余部分

  • 我们怎么删除? 我的意思是......如果我们删除一条线,我们可能需要先前的线来重置整个船体,但是当插入一条新线时,该算法会删除所有不必要的线。
  • 这是另一种方法,解决上面的问题(或类似的问题,例如管理插入,删除,在x点或给定范围内找到最大值等查询)

先感谢您!

答案

要回答你的第一个问题:“如何插入O(logn)?”,你确实可以最终检查O(n)个邻居,但请注意,当你发现需要做一个时,你只需要检查一个额外的邻居删除操作。

关键是如果要插入n个新行,那么最多可以执行n次删除操作。因此,除了在排序数据结构中找到其位置所需的每行O(logn)工作之外,额外工作的总量最多为O(n)。

因此,插入所有n行的总努力是O(n)+ O(nlogn)= O(nlogn),或者换句话说,每行的摊销O(logn)。

另一答案
  1. 该文章声称每次插入时摊销(不是最坏的情况)O(log N)时间。缓冲限制很容易证明(每行最多删除一次,每次检查是最后一行或导致删除一行)。
  2. 文章没有说这个数据结构完全支持删除。我不确定是否有可能有效地处理它们。存在一个障碍:时间复杂度分析基于以下事实:如果我们删除一条线,将来我们将永远不需要它,而在允许删除的情况下则不然。
另一答案

插入可以比O(log n)更快,它可以在O(Log h)中实现,其中h是已经计算的Hull点的集合。批量插入或逐个插入可以每点O(log h)完成。你可以阅读我的文章:

  1. A Convex Hull Algorithm and its implementation in O(n log h)
  2. Fast and improved 2D Convex Hull algorithm and its implementation in O(n log h)
  3. First and Extremely fast Online 2D Convex Hull Algorithm in O(Log h) per point

关于删除:我很确定,但必须证明,它可以在每个点的O(log n + log h)= O(log n)中实现。关于它的文本可以在我的第三篇文章的末尾找到。

以上是关于动态凸壳技巧的主要内容,如果未能解决你的问题,请参考以下文章

Share the Ruins Preservation(Graham算法利用叉积动态维护上下凸壳)

Android课程---Android Studio使用小技巧:提取方法代码片段

VS2015使用技巧 打开代码片段C#部分

26个jQuery代码片段使用技巧

记录--九个超级好用的 Javascript 技巧

VS中添加自定义代码片段——偷懒小技巧