给你一个数列a[1],a[2],...,a[n],每次询问一对l,r,求a[l]+a[l+1]+...+a[r]。
普及组340+的选手肯定知道这题能用前缀和解决。
好,我们改一改:
给你一个数列a[1],a[2],...,a[n],每次修改某个a[i]的值,或者询问一对l,r,求a[l]+a[l+1]+...+a[r]。
修改的时候重新计算前缀和,TLE!怎么办?
不如咱们就不算前缀和吧。
比如n=8,我第一次询问l=1,r=8,怎么算?a1+a2+a3+a4+a5+a6+a7+a8
第二次询问l=1,r=7,怎么算?a1+a2+a3+a4+a5+a6+a7
第三次询问l=1,r=6,怎么算?a1+a2+a3+a4+a5+a6
你看,a1+a2+a3+a4+a5+a6算了这么多遍,是不是很浪费时间?
来,咱们一开始先算出a1+a2+a3+a4+a5+a6是多少,这样每次询问就可以减少很多时间啦!
可是如果我询问(l=1,r=6),(l=2,r=7),(l=3,r=8),怎么办?
事先计算[a1+a2+a3+a4] [a5+a6+a7+a8]对计算(l=2,r=7)没有帮助,还是要a2+a3+a4+a5+a6+a7
我们多算一点东西出来
[a1+a2+a3+a4] [a5+a6+a7+a8]
[a1+a2] [a3+a4] [a5+a6] [a7+a8]
现在呢?a2+(a3+a4)+(a5+a6)+a7,是不是又快了一些呢?
来我们换个更大点的例子,n=32,我们先把这些区间的和算出来
[1..32]
[1..16] [17..32]
[1..8] [9..16] [17..24] [25..32]
[1..4] [5..8] [9..12] [13..16] [17..20] [21..24] [25..28] [29..32]
[1..2][3..4]...[31..32]
1 2 ... 32
好的我们来算a2+a3+...+a31
a2 + (a3+a4) + (a5+...+a8) + (a9+...+a16) + (a17+...+a24) + (a25+...+a28) + (a29+a30) + a31
你会发现,上面预处理的区间是一棵树的结构,每往下一层,区间长度就除以2,那么如果序列长度是100000也不到20层!
怎样改一个数?我们找到最底下的这个点,不断往上走,更新这些结点的和。
于是这个问题就解决啦!