贴个板子,供自己看
分块核心:暴力操作
左端不完整区间,右端不完整区间暴力计算
中间完整区间lazy标记
#include <bits/stdc++.h>
#define N (100000+5)
using namespace std;
int n,k,a[N],lazy[N],pos[N],L[N],R[N];//a原数组,lazy懒标记,pos[i]:i对应的块,L[i]:块i的左端点,R[i]:块i的右端点
void add(int l,int r,int c){//区间加
for(int i=l;i<=min(R[pos[l]],r);i++){//左端不完整区间处理
a[i]+=c;
}
if(pos[l]!=pos[r]){
for(int i=L[pos[r]];i<=r;i++){//右端不完整区间处理
a[i]+=c;
}
}
for(int i=pos[l]+1;i<pos[r];i++) lazy[i]+=c;//中间完整区间处理
}
int main(){
scanf("%d",&n);
k=sqrt(n);//每k个数分1块
int sum=n/k+(n%k!=0);//共分sum个块
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) pos[i]=(i-1)/k+1;//每个数在哪个块
for(int i=1;i<=sum;i++) L[i]=(i-1)*k+1,R[i]=i*k;//左右端点
R[sum]=n;
for(int i=1;i<=n;i++){
int opt,l,r,c;
scanf("%d%d%d%d",&opt,&l,&r,&c);
if(opt==0) add(l,r,c);
else if(opt==1) printf("%d\n",a[r]+lazy[pos[r]]);
}
return 0;
}
原文:https://www.cnblogs.com/Xx-queue/p/12193193.html