一 基本概念
分块算法是将所有数据都分成若干块,维护块内信息,而总询问可被看做是若干块儿的询问的总和。
分块算法将长度为 n 的序列分成若干块,每一块都有 k 的元素,最后一块儿可能少于 k 的元素。为了使时间复杂度均摊,通常将块的大小设为 k=sqrt(n),用 pos[i] 表示第 i 个位置所属的块,对每个块儿都进行信息维护。分块可以解决以下问题。
1 单点更新
一般先将对应的块的懒标记下传,再暴力更新块的状态。
2 区间更新
若区间更新横跨若干块,则只需对完全覆盖的块打上标记,最多需要修改两端的两个块,对两端剩余的部分暴力更新块的状态。
3 区间查询
和区间更新类似,对中间跨过的整个块直接利用块存储的信息统计答案,对两端剩余的部分可以暴力扫描统计。
将整个段分成多个块后进行修改或查询时,对完全覆盖的块儿直接进行修改,像线段树一样标记或累加;对两端剩余的部分进行暴力修改,分块算法遵循“大段维护、局部朴素”的原则。
二 算法说明
1 将序列分块,然后将每个块都标记左右端点 L[i] 和 R[i],对最后一块需要特别处理。
n=10,t=sqrt(10)=3,每 3 个元素为一块,一共分成 4 块,最后一块只有一个元素。
2 用 pos[] 标记每个元素所属的块,sum[] 累加每一块的和值。