分块算法总结

本文介绍了分块算法的基本概念,包括如何确定块的数量和大小,以及如何处理边界情况。核心数据结构和分、查、更新三个关键函数进行了阐述。分块算法可以解决范围最值查询(RMQ)和区间操作等问题,适用于处理大规模数据。文章还讨论了如何在不允许修改值和要求修改值的情况下应用算法,并提及与线段树的对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分块

分块算法顾名思义,就是将一个序列分成若干个部分(块)来解决
线段树也可以解决分块的问题,但这里只介绍分块算法

解决问题:

说是分块,那么一共要分几块呢?
据机房dalao说,分成sqrt(n)为每块长度
这样一来,假设有n个元素的序列,就有 ceil(n/sqrt(n)) 块

核心的数据结构:

struct Block{
int l,r;//块的左右区间端点
int tag;//表示这一整块都增加了tag
//……剩下的根据题目来设计每个块所包含的数据域
};
vector<Block> blo;

vector<int> num;//num[i]:第i个元素所处的块的编号  比如说 123 456 789(n=9)  num[3]=1,num[5]=2

其核心思想就是先解决外部不整块的部分,然后解决中间成块的部分

图1.1
这里红色斜线部分是多余部分,这里我们就需要暴力解决
即:从l到block[l].r暴力
从r到block[r].l暴力
纯红色部分就可以当做一个整体来解决
具体方式还是要依据实际题目来设计算法

设计函数:
这里我们一共包含三个函数:分、查、更新

void build() //分,即分块函数
这个函数的内容是:
1.确定对于当前序列长度为n,一共要分几块
2.确定下来每一块的距离
3.给每一个块确定左端点和右端点
4.对于每一个序列中的元素,确定下来i是属于第几块
注意,这里还要处理末尾的块,因为不一定n都可以被开方
处理方法:左端点的设定与之前一样,但是把右端点设置为n就OK了

void updata() //更新,即在区间内加上或减去

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值