Algorithm 更新及;查询数组中的所有元素>;=其中X是快速变量

Algorithm 更新及;查询数组中的所有元素>;=其中X是快速变量,algorithm,data-structures,Algorithm,Data Structures,形式上,我们得到一个带有一些初始值的数组。然后我们有3种类型的查询:- 点更新:在给定位置增加1 范围查询:计算元素数>=x,其中x作为输入 范围更新:将所有元素>=x递减1,其中x作为输入 N=105,Q=105(数组中的元素数,查询数) 我试着用段树来做这件事,但操作2,3可能比O(n)更糟糕,即使我们不知道要准确地更新哪个“范围”,所以我们可能会遍历整个段树 注意:我想澄清的是,如果我们需要在对数最坏情况下做所有3个运算,即O(logn),因为只有这样我们才能快速完成,线性方法不能像Q=1

形式上,我们得到一个带有一些初始值的数组。然后我们有3种类型的查询:-

  • 点更新:在给定位置增加1
  • 范围查询:计算元素数>=x,其中x作为输入
  • 范围更新:将所有元素>=x递减1,其中x作为输入
  • N=105,Q=105(数组中的元素数,查询数)

    我试着用段树来做这件事,但操作2,3可能比O(n)更糟糕,即使我们不知道要准确地更新哪个“范围”,所以我们可能会遍历整个段树


    注意:我想澄清的是,如果我们需要在对数最坏情况下做所有3个运算,即O(logn),因为只有这样我们才能快速完成,线性方法不能像Q=10^5n=10^5那样工作,所以最坏情况可能是O(n^2),即10^10运算,这显然是不可行的。

    考虑到你们正在谈论的105项,不用说需要添加或删除项,在我看来,显而易见的数据结构应该是一个简单的排序向量

    操作复杂性:

  • 点更新:O(1)+O(m)(其中
    m
    是后续元素的数量,等于更新前的值)
  • 范围查询:O(logn)+O(m)(其中
    n
    是范围的开始,
    m
    是范围中的元素)
  • 范围更新(与范围查询相同)
  • 要确定“快”对你来说意味着什么有点困难,但是理论上1的最快可能是O(1),所以我们已经在某个恒定的最优因子范围内

    对于2和3,即使我们能够以恒定的复杂度进行查找,我们也几乎只能使用O(m)进行更新。由于Log2100000=~16.6,大部分时间O(m)项将占主导地位(即,更新部分将涉及与搜索一样多的操作,除非给定的
    x
    是集合中最后17项之一)


    我怀疑这么小的一个集合有什么意义,但是如果您可能需要处理一个大得多的集合,并且集合中的项目可以合理地预测分布,那么可能值得考虑使用插值搜索而不是二进制搜索。使用可预测分布,这将减少预期数量与大约O(log n)进行比较的ber。在这种情况下,这大约是4(但通常具有更高的常数因子)。这可能是105个项目的胜利,但也可能不是。如果您可能需要处理一组(例如)108项或更多,这将更有可能是一个实质性的胜利。

    以下可能不是最佳的,但是我今晚能想到的最好的

    让我们先把问题转向一边,而不是从索引到值的映射,让我们考虑一个从值到索引集的映射。现在,一个点更新包括从一个集合中移除索引并将其添加到另一个集合。范围更新包括简单地将索引集从一个值移动到另一个值或者采取两个索引的联合。x集。范围查询涉及折叠范围中的值对应的集合。快速浏览维基百科表明,传统的集合合并非常有用。不幸的是,从集合中删除元素一点用都没有


    幸运的是,有一个更新的数据结构支持!它可以很自然地处理点更新和范围更新。不幸的是,范围查询将需要检查所有数组元素,即使范围内的元素很少。

    10^5没有那么多…只需复制和排序数组,保留最大值和最小值以及二进制搜索即可r轴元素大于或等于x(适用于2 in O(lg n)),对于3,再次对轴元素进行二进制搜索,然后向下交换元素,它们不应该出现那么多气泡;在最坏的情况下,3将是O(n)@伊瓜罗:你永远不必向下冒泡任何项目来维持#3中的顺序。因为你只递减1,并且你将所有项目>=修改为某个值,所以递减第一个项目之前的项目必须始终比递减的项目至少少1,所以递减1不会强制改变顺序。递减之后,最小的受影响元素可能等于上一个元素,但不能小于它。是的,你是对的,因为项目值缩小了1,是出现气泡的轴,而不是项目(我承认,我写下了一个测试来让自己清楚xD),感谢您指出,查询的数量与元素的数量顺序相同,这一事实强烈表明“正确”的答案将涉及某种摊销论证。O(m)的速度非常慢。如果Q=10^5,这种方法将需要O(n^2),所以在最坏的情况下,我们将有10^10个操作要做,这是不可行的。我们需要在对数时间内做所有的操作,即O(logn)作为最坏的情况(并且可以做,因为问题要求我们这个解决方案:))谢谢,这对我来说是新的:)但我想所有3个操作仍然没有减少到O(logn),不是吗?@Shikhar,我不是专家,所以我不知道这样的事情是否为人所知。“我只是一个数学系的学生。@Shikhar,没有办法将范围查询减少到O(logn)。打印k个元素至少需要O(k)。问题是,在仍然支持其他操作的情况下,是否有可能实现这一点(或接近这一点)。我们不需要打印k个元素……我们只需要打印这些元素的数量>=x。就是这样,所以这是可以做到的,这就是问题想要我们做的:)@Shikhar,好吧,你应该这么说!您编写了“打印所有元素>=x”。您应该写“打印元素数>=x”。这应该更容易!