是否有可能计算出在分摊的次线性时间内以给定数量为模的一组数的最小值?

时间:2013-07-24 01:58:57

标签: algorithm data-structures

是否存在表示(64位)整数的大集合S的数据结构,它从空开始并支持以下两个操作:

  • insert(s)将号码s插入S;
  • minmod(m)会返回s中的S号,以使s mod m最小化。

一个例子:

    insert(11)
    insert(15)
    minmod(7) -> the answer is 15 (which mod 7 = 1)
    insert(14)
    minmod(7) -> the answer is 14 (which mod 7 = 0)
    minmod(10) -> the answer is 11 (which mod 10 = 1)

我有兴趣尽量减少n这类操作所花费的最长总时间。显然可以只为S维护一个元素列表,并为每个minmod操作迭代它们;插入为O(1),minmod为O(|S|)O(n^2)次操作需n次(例如,n/2 insert操作后跟{ {1}} n/2操作大约需要minmod次操作。

那么:对于一系列n^2/4操作,是否可能比O(n^2)做得更好?可能nO(n sqrt(n))?如果这是可能的,那么我也有兴趣知道是否有数据结构另外允许从O(n log(n))中删除单个元素,或删除间隔内的所有数字。

2 个答案:

答案 0 :(得分:7)

另一种基于平衡二叉搜索树的想法,如Keith的答案。

假设到目前为止所有插入的元素都存储在平衡的BST中,我们需要计算minmod(m)。考虑我们的集合S作为数字子集的并集,以[ 0,m-1],[m,2m-1],[2m,3m-1] 为间隔。答案显然是我们在每个时间间隔内的最小数字。因此,我们可以查找树以找到该间隔的最小数量。这很容易做到,例如,如果我们需要在 [a,b] 中找到最小数字,如果当前值大于 a ,我们将向左移动,并且否则,跟踪到目前为止我们遇到的 [a,b] 的最小值。

现在,如果我们假设在 [1,2 ^ 64] m 均匀分布 ,那就让我们吧计算我们需要的查询数量的数学期望。

对于 [2 ^ 63,2 ^ 64-1] 中的所有 m ,我们需要 2 查询。这种可能性 1/2 对于 [2 ^ 62,2 ^ 63-1] 中的所有 m ,我们需要 4 查询。这种可能性 1/4 ...
对于 [1,64] 中的 k ,数学期望将是 sum [1 /(2 ^ k)* 2 ^ k] ,这是 64 查询。

因此,总而言之, 平均 minmod(m)查询复杂性将为 O(64 * logn)。通常,如果我们 m 的上限未知,则 O(logm logn) 。众所周知,BST更新 O(logn),因此 n 查询时的整体复杂性将为 O(n 10gm的* logn)时间

答案 1 :(得分:2)

部分答案对于评论来说太大了。

假设您将S实现为平衡二叉搜索树。

当你寻找S.minmod(m)时,天真地走在树上,费用是O(n ^ 2)。

然而,在步行期间的给定时间,到目前为止你有最好的(最低的)结果。您可以使用它来避免在以下情况下检查整个子树:

bestSoFar < leftChild mod m

rightChild - leftChild < m - leftChild mod m

如果公式间距b / w集合中的数字小于m的公共值,这只会有很大帮助。

第二天早上更新......

格里戈尔更好,更全面地阐述了我的想法,并展示了它如何适用于“大型”m。他还展示了“随机”m通常是如何“大”的,所以效果很好。

Grigor的算法对于大m非常有效,因此需要考虑更小m的风险。 因此很明显,您需要考虑m的分布情况,并根据需要针对不同情况进行优化。 例如,可能值得简单地跟踪非常小m的最小模数。

但是假设m ~ 2^32?然后搜索算法(当然也是给定的,否则)需要检查2^32间隔,这可能相当于搜索整个集合。