恒定时间级联计算是否可行?

时间:2017-10-08 06:47:04

标签: c++ arrays performance data-structures

这是一个关于计算机技术限制的教育目的问题 我有一种心态认为下面的程序是不可能创建的。

我们要说我必须建立一个累积的统计数据结构 这是规范: -

  • 用户可以在update(i,value) data[i] O(1) getAccu(i)(平均情况)。
  • 用户可以在data[0]+data[1]+...+data[i]中查询O(1) = #include <iostream> #include <vector> int data[5]={0,1,2,3,4}; int accu[5]={0,1,3,6,10}; /** assume that index always >=1 */ void update(int index,int value){ //O(n) i.e. O(array length) data[index]=value; for(int n=index-1;n<5;n++){ accu[n]=accu[n-1]+data[n]; } } int getAccu(int index){ //O(1) return accu[index]; } int main(){ update(2,12); //note: data = 0,1,12,3,4 // accu = 0,1,13,16,20 std::cout<<getAccu(3)<<std::endl; //16 //update() ... getAccu()... update() ... } (平均情况)。
  • 我不能以任何方式承担调用这两个函数的顺序。

这是我的代码(coliru demo) 但它不符合上述要求: -

update(index,value)

不限制存储器的大小和数据结构的类型,
可以使getAccu(index)O(1)两个函数都成为let randomValue = arc4random_uniform(10)+1 let randomImage = QuoteImages[randomValue] 吗?

如果是,怎么样?如果不是,为什么?

对于这个不起眼的话题感到抱歉。我找不到更适合的人。

1 个答案:

答案 0 :(得分:2)

在恒定时间内做所有事情似乎很乐观。如果您不介意O(log n)复杂性,您可以维护一个平衡的二叉树,在每个节点中存储以该节点为根的子树总数。

更新一个值时,只需更新从根到该元素的路径中的log n小计。

计算累加器只是从根位置找到正确的节点,并在每次向右时添加左小计。

不是急切地进行更新,而是可以将它们以恒定的时间添加到待更新项目列表中,然后当您收到查询并且该列表不为空时,您可以在{{1或者,如果有许多更新只更新log n中的值并重新计算O(1)中的整个累加器,但如果您在2个查询之间获得许多更新,那么这只值得一试。