我对在https://www.geeksforgeeks.org/two-dimensional-segment-tree-sub-matrix-sum/的“修改查询”复杂度有些困惑。该文章底部指出其复杂度为O(2 * n * log n * log m)。为什么不只是O(log n * log m)? 额外的线性项n从哪里来?
我对在https://www.geeksforgeeks.org/two-dimensional-segment-tree-sub-matrix-sum/的“修改查询”复杂度有些困惑。该文章底部指出其复杂度为O(2 * n * log n * log m)。为什么不只是O(log n * log m)? 额外的线性项n从哪里来?
def update(pos, low, high, x, y, val):
if (low == high) :
finalUpdate(1, 1, 4, x, val, pos)
else :
mid = (low + high) // 2
if (low <= y and y <= mid) :
update(2 * pos, low, mid, x, y, val)
else :
update(2 * pos + 1, mid + 1,
high, x, y, val)
for i in range(1, size):
fin_seg[pos][i] = (fin_seg[2 * pos][i] +
fin_seg[2 * pos + 1][i])
n
来源的地方。但我会说复杂度为 O(n * log(m) + log(n),因为最终的更新仅调用一次且只进行了
log(n) 次更改。
n
因素的实现只重新计算依赖于更改元素的节点的实现复杂度为 O(log(n)*log(m))
。这可以通过在 finalUpdate
中跟踪更改的元素来实现。
def finalUpdate(pos, low, high, x, val, node):
if (low == high) :
fin_seg[node][pos] = val
return [pos]
else :
mid = (low + high) // 2
if (low <= x and x <= mid) :
changes = finalUpdate(2 * pos, low, mid,
x, val, node)
else :
changes = finalUpdate(2 * pos + 1, mid + 1,
high, x, val, node)
changes.append(pos);
fin_seg[node][pos] = (fin_seg[node][2 * pos] +
fin_seg[node][2 * pos + 1])
return changes
finalUpdate
是二分查找,因此它将被称为 log(m)
递归,每次调用都会更改一个元素,因此更改的次数将是 log(m)。def update(pos, low, high, x, y, val):
if (low == high) :
changes = finalUpdate(1, 1, 4, x, val, pos)
else :
mid = (low + high) // 2
if (low <= y and y <= mid) :
changes = update(2 * pos, low, mid, x, y, val)
else :
changes = update(2 * pos + 1, mid + 1,
high, x, y, val)
for i in changes:
fin_seg[pos][i] = (fin_seg[2 * pos][i] +
fin_seg[2 * pos + 1][i])
return changes;
更新将进行二分查找,将被称为log(n)
次,每次调用将重新计算log(m)
个节点。
m
和n
搞混了。 - Bob