分块入门
在这你可以看到全oier中最弱的分块水平
理论
分块是一种思想,把一个整体划分为若干个小块,对整块整体处理,零散块单独处理。
分块不要求答案之间具有结合律,所以可以解决一些用线段树难以解决的问题。
分块的块长需要根据题目来进去调整,可一般来说,块长一般为 \(\sqrt{N}\)
比如对于这题来说,我们预处理好每个块的和。
对于修改操作,我们给整块打上加标记,散块直接暴力处理即可;
int l1=cx[l],r1=cx[r];
if(l1==r1)
{
for(int i=l;i<=r;i++)
sum[l1]+=x,a[i]+=x;
}
else
{
for(int i=l;i<=l1*size;i++)
sum[l1]+=x,a[i]+=x;
for(int i=l1+1;i<r1;i++)
mark[i]+=x;
for(int i=(r1-1)*size+1;i<=r;i++)
sum[r1]+=x,a[i]+=x;
}
对于查询操作,我们直接加上整块和散块的答案即可;
int s=0;
int l1=cx[l],r1=cx[r];
if(l1==r1)
{
for(int i=l;i<=r;i++)
s+=a[i]+mark[l1];
}
else
{
for(int i=l;i<=l1*size;i++)
s+=a[i]+mark[l1];
for(int i=l1+1;i<r1;i++)
s+=sum[i]+mark[i]*size;
for(int i=(r1-1)*size+1;i<=r;i++)
s+=a[i]+mark[r1];
}
return s;
这样我们优雅的暴力就打好了,我们来分析一下时间复杂度,假设我们的块长为\(B\),对于每次操作,最多有\(\frac{N}{B}\) 块,散块最多长为\(B\) ,复杂度是\(O(\frac{N}{B}+2B)\) 。
当\(B\) 取到 \(\sqrt{N}\) 是,复杂度为\(O(3\sqrt{N})=O(\sqrt{N})\) ,所以总体复杂度就是\(O(M\sqrt{N})\) 。
练习
luogu P2801
对于这一题我们发现用线段树不好解决,又发现询问次数非常小,于是尝试使用分块。
我们对于每个块排序,查询时就能用二分查询了。
对于修改操作,我们对整块打上标记,对散块暴力修改后再排序
int l1=cx[l],r1=cx[r];
if(l1==r1)
{
for(int i=l;i<=r;i++)
sum[l1]+=x,a[i]+=x;
for(int i=l1*size-size+1;i<=min(l1*size,n);i++)
b[i]=a[i];
sort(b+(l1-1)*size+1,b+min(l1*size,n)+1);
}
else
{
for(int i=l;i<=l1*size;i++)
sum[l1]+=x,a[i]+=x;
for(int i=l1*size-size+1;i<=l1*size;i++)
b[i]=a[i];
sort(b+(l1-1)*size+1,b+l1*size+1);
for(int i=l1+1;i<r1;i++)
mark[i]+=x;
for(int i=(r1-1)*size+1;i<=r;i++)
sum[r1]+=x,a[i]+=x;
for(int i=r1*size-size+1;i<=min(r1*size,n);i++)
b[i]=a[i];
sort(b+(r1-1)*size+1,b+min(r1*size,n)+1);
}
对于查询操作,我们对整块二分查询,对散块暴力查询
int s=0;
int l1=cx[l],r1=cx[r];
if(l1==r1)
{
for(int i=l;i<=r;i++)
if(a[i]+mark[l1]>=x)s++;
}
else
{
for(int i=l;i<=l1*size;i++)
if(a[i]+mark[l1]>=x)s++;
for(int i=l1+1;i<r1;i++)
{
int L=(i-1)*size,R=i*size;
if(R>n)R=n;
int o=R;
while(L+1<R)
{
int mid=(L+R)>>1;
if(b[mid]+mark[i]>=x)R=mid;
else L=mid;
}
s+=o-R+1;
if(b[R]+mark[i]<x)s--;
}
for(int i=(r1-1)*size+1;i<=r;i++)
if(a[i]+mark[r1]>=x)s++;
}
return s;
对于修改的时间复杂度:\(O(log(\sqrt{n})\sqrt{n})\) 。
对于查询的时间复杂度:\(O(log(\sqrt{n})\sqrt{n})\) 。
总时间复杂度为:\(O(qlog(\sqrt{n})\sqrt{n})\) ,可以通过此题。

浙公网安备 33010602011771号