前言
分块可以解决几乎全部的区间查询区间更新等问题,功能比线段树和树状数组要强大,但是时间复杂度会更大一点。其实分块就是一种优化过的暴力,它是对于整体进行像线段树一样的维护,对局部进行暴力的修改。
原理
顾名思义分块分块,我们把长度为n的序列分为若干块。维护块内信息即可。
又要问了,要多大呢?通常将块的大小设为 n \sqrt n n ,用pos数组储存每个块的位置。
最后分完有剩,那么剩余的单独为一个块。

我们用线段树的例题来介绍传送门luoguP3372
题目要求:
1.区间更新:
我们找在这个区间有多少个块是全部在里面的,因为这些块全要更新,我们可以添加懒惰标记,下次要用时才更新。
对于部分在区间的块,我们只有暴力的把这些在区间内的点更新即可、
2.区间查询:
还是讨论如果被区间包含的块,就直接加上处理懒标的值和之前的和即可。
部分在区间的块,就暴力计算值即可。
代码非常简单。也好理解。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int n,m,a[N];
int pos[N],sum[N],L[N],R[N],lz[N];
//块的位置,块的和,块的左区间和右区间,懒惰标记
inline void build()
{
int t=sqrt(n*1.0);
int num=n/t;
if(n%t) num++;//如果有剩余,再加一个块
for(int i=1;i<=num;i++)
{
L[i]=(i-1)*t+1;//每个块的范围
R[i]=i*t;
}
R[num]=n;//最后一个块的右区间是n
for(int i=1;i<=num;i++)
for(int j=L[i];j<=R[i];j++)
{
pos[j]=i;//该点属于哪个块
sum[i]+=a[j];//统计和
}
}
inline

分块算法是一种优化后的暴力解法,适用于区间查询和更新问题。通过将序列分块,部分块完全在区间内时使用线段树策略处理,部分块则进行暴力更新。文章介绍了如何确定块大小,以及区间更新和查询的具体步骤,并提供了两道相关例题以加深理解。
最低0.47元/天 解锁文章
1449

被折叠的 条评论
为什么被折叠?



