给定一个初始化为0的数组arr,即arr [i] = 0,其中0 <0。我&lt; n
在它上面执行两个操作
更新k r x
更新执行以下操作:
for(i=k;i<=r;i++)
{
arr[i]=x;
x+=x;
}
查询k r
查询计算以下总和:
for(i=k;i<=r;i++)
{
sum+=arr[i];
}
print(sum);
我的解决方案:
我想到了蛮力,但它很慢。我想到了段树,但是在段树更新中是以恒定量执行的,所以它失败了。什么可能是一个很好的算法来解决这个问题?
约束
数组的大小是&lt; = 10 ^ 5
操作次数(更新,查询)&lt; = 10 ^ 5
答案 0 :(得分:2)
您正在寻找的是细分树中的延迟传播。 我们创建一个数组lazy [],其大小与段树数组的大小相同。我们的想法是,我们可以通过推迟更新来避免更新中的递归调用,并仅在需要时执行这些更新。
我的代码执行预定义数据的更新和总和提取,您可以使用main来接受所需模式中的用户数据,并添加x + = x等调整。
我建议您打开代码并并排阅读下面的解释,以便更好地理解,因为懒惰传播通常很难掌握。
工作原理:
更新数组索引的分段树,从qs(查询开始)到qe(查询结束):
- &GT;如果当前段树节点有任何挂起 更新,然后我们分配该节点(lazy_value)*(它表示的间隔长度)并将其子项的延迟值指定为new_value
- &GT;如果当前节点的范围完全在 更新查询范围。
i) Update the Current node, by assigning it (lazy_value)*(length of interval it represents)
ii) Postpone updates to children by setting lazy values for children nodes as new_value
- &GT;如果当前节点的范围与更新重叠 范围,遵循与上述相同的方法 更新
一个。重复左右儿童。
湾使用left的结果更新当前节点 和正确的电话。
现在,当我们使用get_sum过程时,如果当前节点有任何挂起的更新并且推迟了对子节点的更新,我们也会更新当前节点。
总的来说,这里很难解释懒惰传播的整个工作,但我希望代码和解释有所帮助。
有关延迟传播的更多信息,请参阅
https://www.hackerearth.com/notes/segment-tree-and-lazy-propagation/