分块浅谈
Posted lcguo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分块浅谈相关的知识,希望对你有一定的参考价值。
其实分块是一种我认为比较简单的算法,可以看作一种暴力。。。
步入正题
分块的思想其实就是在进行区间修改时,将序列分成几块,如果要修改的区间有一个整块的话,将这一个整块做一个标记,其他部分就暴力修改就好了。
例题一
给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值。
先讲一下区间修改
这是最基本的区间修改(a,b):
for(int i=a;i<=min(k[a]*ks,b);i++)
v[i]+=c;
if(k[a]!=k[b])
for(int i=(k[b]-1)*ks+1;i<=b;i++)
v[i]+=c;
for(int i=k[a]+1;i<=k[b]-1;i++)
bj[i]+=c;
k[i]
表示第 (i) 个数在哪个块中
bj[i]
表示第 (i) 块这一整块所加上的数
v[i]
表示第 (i) 个数的值
其中
for(int i=a;i<=min(k[a]*ks,b);i++)
是暴力枚举以a为左端点时不完整的块中的每一个数。
而for(int i=(k[b]-1)*ks+1;i<=b;i++)
是暴力枚举以b为右端点时不完整的块中的每一个数。
for(int i=k[a]+1;i<=k[b]-1;i++) bj[i]+=c;
是对(a)到(b)之间的整块进行整块标记。
单点查询:
v[r]+bj[k[r]]
即该点的值加上它所在的块的标记
然后输出即可
(未完待续)
以上是关于分块浅谈的主要内容,如果未能解决你的问题,请参考以下文章