我有一系列k个节点N1
,N2
,N3
,... Nk
,每个节点都会被连续命中(可能会跳过)。< / p>
每当我访问其中一个节点时,我需要+ =从前一个节点到达那里的时间。棘手的部分是,如果我在没有到达N1
的情况下回到Nk
,则应删除这些+ =更新。
一种方法是在每个节点中保留两个量:x和y。当我们跳节点时,我们+ =值为y。如果我们到达N1
,我们会将y重置为0.如果我们达到Nk
,我们会为每个节点执行x += y
。
问题在于,每当我们点击Nk
时,它都需要进行O(n)操作 - 即使序列在不命中{{}的情况下返回N1
可能不常见。 1}}。如果没有在每次迭代到达结束时进行O(n)“提交”,是否有更智能的方法更有效地执行此操作?
考虑这个包含3个节点的示例:Nk
,N_1
,N_2
:
左边显示了迭代中命中的节点的子序列,右边显示了什么 累积计数器应包含:
N_3
答案 0 :(得分:2)
您可以在每个节点中维护两个累加器(accum_[2]
),以及在到达第k个节点时递增的全局1位计数器(k_counter
)。然后保持accum_[k_counter]
始终具有每个节点的正确累积值的不变量。在此方案中,如果您跳过节点,则必须访问它们,并对它们执行node[i] += 0
。这个要求可以通过访问计数器进行优化,我将作为练习留下: - )。
enum { K = 100 };
struct Node *node;
struct Node {
static bool k_counter;
unsigned accum_[2];
unsigned id_;
Node () : accum_(), id_(this - node + 1) {}
void operator += (unsigned time_data) {
accum_[!k_counter] = accum_[k_counter] + time_data;
if (id_ == K) k_counter = !k_counter;
}
operator unsigned () const { return accum_[k_counter]; }
};
bool Node::k_counter;
node = new Node[K];