可参考:
「分块」数列分块入门1 – 9 by hzwer:http://hzwer.com/8053.html
前言
\quad 首先,我们来考虑这样一个模型:有一段连续的序列 a [ 1 ] ∼ a [ n ] a[1]\sim a[n] a[1]∼a[n],现在我们需要执行几类操作:
- 求出其中一段区间的和
\, 这时我们可以使用前缀和,记录 a [ 1 ] ∼ a [ i ] 的 和 为 s u m [ i ] a[1]\sim a[i]的和为sum[i] a[1]∼a[i]的和为sum[i],显然 s u m [ i ] = s u m [ i − 1 ] + a [ i ] sum[i]=sum[i-1]+a[i] sum[i]=sum[i−1]+a[i],直接 s u m [ r ] − s u m [ l − 1 ] sum[r]-sum[l-1] sum[r]−sum[l−1]即可 - 区间加上某个值
\, 这时我们可以使用线段树(能解决区间和、区间最值、计数等问题的数据结构)来解决 - 查询一段区间上有多少个数 < k ( k > 0 ) <k(k>0) <k(k>0),且每次不一样,极其的多。
\, 这时的某人(显然不是我) :???????
分块详解
这时我们学习一个很朴素很暴力的算法:分块,内容很多,我们只说一部分,剩下的请大家自己学习
分块的基本思想是通过适当的划分,预处理一部分信息并保存下来,用空间换取时间,达到时空平衡。
顾名思义,就是把一段序列分成一小块一小块得来处理,维护。我们把一段当成一个整体,只记录维护整体的有关信息,就是分块。
对于前言说的那道题,很朴素的做法:
- 从询问区间的 l l l到 r r r扫过去,每回加上扫到的值,即 s u m = ∑ i = l r a [ i ] sum=\sum_{i=l}^{r}a[i] sum=∑i=lra[i]
- 直接把 a [ i ] a[i] a[i]重新赋值 a [ i