这是一个关于计算机技术限制的教育目的问题 我有一种心态认为下面的程序是不可能创建的。
我们要说我必须建立一个累积的统计数据结构 这是规范: -
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]
吗?
如果是,怎么样?如果不是,为什么?
对于这个不起眼的话题感到抱歉。我找不到更适合的人。
答案 0 :(得分:2)
在恒定时间内做所有事情似乎很乐观。如果您不介意O(log n)
复杂性,您可以维护一个平衡的二叉树,在每个节点中存储以该节点为根的子树总数。
更新一个值时,只需更新从根到该元素的路径中的log n小计。
计算累加器只是从根位置找到正确的节点,并在每次向右时添加左小计。
不是急切地进行更新,而是可以将它们以恒定的时间添加到待更新项目列表中,然后当您收到查询并且该列表不为空时,您可以在{{1或者,如果有许多更新只更新log n
中的值并重新计算O(1)
中的整个累加器,但如果您在2个查询之间获得许多更新,那么这只值得一试。