分块算法介绍

一 基本概念

分块算法是将所有数据都分成若干块,维护块内信息,而总询问可被看做是若干块儿的询问的总和。

分块算法将长度为 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[] 累加每一块的和值。

3 区间更新

将 [i,j] 区间的元素都加上 d。

a 求 l 和 r 所属的块,p=pos[l],q=pos[r]。

b 若属于同一块(p=q),则对该区间的元素进行暴力修改,同时更新该块的和值。

c 若不属于同一块,则对中间完全覆盖的块打上懒标记,add[i]+=d,对首尾两端的元素进行暴力修改。

将 [3,8]区间的元素都加上 5。

4 区间查询

查询 [l,r] 区间的元素和值。

a 求 l 和 r 的所属块,p=pos[l],q=pos[r]。

b 若属于同一块(p=q),则对该区间的元素进行暴力累加,然后加上懒标记上的值。

c 若不属于同一块,则对中间完全覆盖的块累加 sum[] 值和懒标记上的值,然后对首尾两端暴力累加元素值及懒标记值。

查询[2,7]区间的元素和值。

首尾块=5+7+add[1]*(3-2+1)+9+add[3]*(7-7+1)=78

中间块=42+add[2]*(6-2+1)=42+5*3=57

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值