定义:

块状数组是基于分块思想的数据结构,较基于分治思想的数据结构如线段树、平衡树等效率较低,但通用性更强。在块状数组的基础上加以扩展,就可以得到块状链表。

原理:

普通数组在处理一些区间问题时,复杂度通常会退化至O(n)。一个朴素的想法就是将这个数组分为若干个子区间,同时维护这些子区间的统计值,如区间和、区间最值等。对于某个子区间,如果操作区间覆盖子区间,则在整体上进行修改并打标记。如果操作区间部分覆盖子区间,则将该块标记下放,对区间中被覆盖部分的元素进行暴力操作。

设数组长度为n,将其分为s块,每块c个元素,那么一次操作最坏情况是遍历所有块,复杂度为O(s)。对于不需暴力处理的块,处理的复杂度为O(1)。易知需要暴力处理的块最多只有2个,而暴力处理一个块的最坏情况是遍历块中几乎所有元素,复杂度为O(c)。总复杂度为O(s+c)。根据s*c=n,由基本不等式知,当s,c取近似n½ 时,总复杂度最小,为O(n½)。这就是分块的思想。对这个算法进行分析后会发现,我们对元素的处理方法本质上还是暴力,只是通过一些数学方法使暴力的复杂度降到了我们可以接受的范围。因此分块思想又被称为“根号的暴力”。

下面给出本人块状数组的写法,以区间和为例。


分块

定义一个结构体数组,数组元素个数为块的个数。数组里存储每一个块的左右端点,以及区间信息和标记信息。

同时保留原数组,再额外定义一个数组belong,belong[i]里存储i所属的块的下标。

#define LL long long
struct block{int l,r;LL s,d;}b[maxm];
LL a[maxn],belong[maxn],sum[maxn];
View Code

相关文章:

  • 2021-07-17
  • 2021-09-13
  • 2021-06-16
  • 2022-03-03
  • 2021-12-21
  • 2022-12-23
  • 2022-12-23
  • 2021-09-25
猜你喜欢
  • 2021-06-19
  • 2021-09-24
  • 2022-01-19
  • 2022-12-23
  • 2022-02-07
  • 2021-08-21
  • 2022-01-26
相关资源
相似解决方案