是否有一个数据结构表示一个大的(64位)整数集S
,它以空开始并支持以下两个操作:insert(s)
将数字s
插入到S
中;minmod(m)
返回s
中的数字S
,使s mod m
最小。
例如:
插入(11)
插入(15)
minmod(7)->答案是15(mod 7=1)
插入(14)
minmod(7)->答案是14(mod 7=0)
minmod(10)->答案是11(mod 10=1)
我感兴趣的是最小化在一个序列中花费的最大总时间。很明显,只需为n
维护一个元素列表,并为每个S
操作迭代它们;然后insert isminmod
和minmod isO(1)
,这将花费O(|S|)
时间进行O(n^2)
操作(例如,n
n/2
操作之后的insert
n/2
操作将大约花费minmod
操作)。
那么:对于一系列的n^2/4
操作,有没有可能比O(n^2)
做得更好呢?可能n
或O(n sqrt(n))
?如果这是可能的,那么我还想知道是否有数据结构允许从O(n log(n))
中删除单个元素,或者在一个间隔内删除所有数字。
最佳答案
另一种基于平衡二叉搜索树的思想,如Keith的答案。
假设到目前为止所有插入的元素都存储在平衡的bst中,我们需要计算minmod(m)
。把我们的集合S
看作一个数子集的并集,位于区间[0,m-1]、[m,2m-1]、[2m,3m-1]……答案显然是我们在每一个区间内的最小值。因此,我们可以通过查找树来找到最小的间隔数。这很容易做到,例如,如果我们需要在[a,b]中找到最小值,如果当前值大于a,我们将向左移动;否则,我们将向右移动,跟踪到目前为止遇到的[a,b]中的最小值。
如果我们假设m在[1,2^64]中均匀分布,那么我们来计算我们需要的查询数的数学期望。
对于[2^63,2^64-1]中的所有m,我们需要两个查询。概率是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(logmlogn)。BST更新是已知的O(Logn),因此在N个查询的情况下的总体复杂度将是O(nLogm *Logn)。