分块
高级的暴力,把序列分成一块一块的,利用加懒标记的方式进行区间操作。而没有被分成块的就直接暴力修改,所以时间复杂度方面感觉很玄学。
例一
给一个长度为n的序列,每次给l,r和c,表示把区间l~r都加c,或者输出a[r]的值
一开始只知道原理而没见过板子的时候
void fenkuai()
{
for(int i=1;i<=n;i+=m)kuaiz[++tot]=i;
kuaiz[++tot]=kuaiz[tot-1]+m;
}//n为序列长度,m为块的大小
写下这种幼稚的板子,用 k u a i z [ t o t ] kuaiz[tot] kuaiz[tot] 记录每一块的左端点在序列中的下标。
然后
void xg(int x,int y,int z)
{
int p=lower_bound(kuaiz,kuaiz+tot,x)-kuaiz;
int q=upper_bound(kuaiz,kuaiz+tot,y)-kuaiz;
for(int i=p+1;i<q;i++)lan[i]+=z;
for(int i=x;i<kuaiz[p];i++)a[i]+=z;
for(int i=kuaiz[q-1];i<=y;i++)a[i]+=z;
return;
}
以这种错误的方式进行整块整块的懒标记,和非整块部分的直接修改,然后听取 W A WA WA 声一片。(当然不排除思路没错但写法有误。)然后在高强度自闭下看了别人的写法。

后来也确实有人的实现跟我一开始所想的差不多
void change(int ll,int rr,long long d)
{
int p=pos[ll],q=pos[rr];
if(p==q)
{
for(int i=ll;i<=rr;i++) a[i]+=d;
sum[p]+=d*(rr-ll+1);
}
else
{
for(int i=p+1;i<q;i++) add[i]+=d;
for(int i=ll;i<=r[p];i++) a[i]+=d;
sum[p]+=d*(r[p]-ll+1);
for(int i=l[q];i

最低0.47元/天 解锁文章
5万+

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



