分块
分块算法顾名思义,就是将一个序列分成若干个部分(块)来解决
线段树也可以解决分块的问题,但这里只介绍分块算法
解决问题:
说是分块,那么一共要分几块呢?
据机房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
其核心思想就是先解决外部不整块的部分,然后解决中间成块的部分
即
这里红色斜线部分是多余部分,这里我们就需要暴力解决
即:从l到block[l].r暴力
从r到block[r].l暴力
纯红色部分就可以当做一个整体来解决
具体方式还是要依据实际题目来设计算法
设计函数:
这里我们一共包含三个函数:分、查、更新
void build() //分,即分块函数