数列分块入门 1
_Fireflies_ · · 题解
题目传送门
算法介绍:
分块是一种暴力优雅的数据结构。
分块,顾名思义,在处理一个长度为
思路:
显然本题就是分块模板,加法对整块打标记,对零散部分暴力处理即可,复杂度
代码:
注意 long long。
#include <bits/stdc++.h>
using namespace std;
inline long long read()
{
long long x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
long long n;
long long op,l,r,c;
struct node{
long long l,r;
long long add;
long long m[605];
}k[605];
long long B=600;
long long a[300005];
long long mq=0,ms=0;
int main(){
n=read();
for(long long i=1;i<=n;i++){
a[i]=read();
}
k[0].l=1;
k[0].r=B;
k[0].add=0;
for(long long i=1;i<=300000;i++){
ms++;
if(ms==B+1){
mq++;
ms=1;
k[mq].l=(mq*B)+1;
k[mq].r=(mq+1)*B;
k[mq].add=0;
}
if(i>n) k[mq].m[ms]=0;
else k[mq].m[ms]=a[(mq*B)+ms];
}
for(long long i=1;i<=n;i++){
op=read();
l=read();
r=read();
c=read();
if(op==0){
for(long long j=0;j<=mq;j++){
if(l<=k[j].l&&r>=k[j].r) k[j].add+=c;
else if(k[j].r<l||k[j].l>r) continue;
else{
for(long long o=1;o<=B;o++){
if(l<=(j*B)+o&&r>=(j*B)+o){
k[j].m[o]+=c;
}
}
}
}
}
else{
if(r%B==0) cout<<(k[(r/B)-1].m[B]+k[(r/B)-1].add);
else cout<<(k[r/B].m[r%B]+k[r/B].add);
cout<<endl;
}
}
return 0;
}
572ms,人傻常数大。