给定长度为n的序列;
区间加,区间查询;
原来分块和树状数组,线段树差不多。。。
都是用空间复杂度来减轻时间复杂度,以达到平衡。
分块比较的直观,通用
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
long long a[maxn],sum[maxn],add[maxn];
int l[maxn],r[maxn];
int pos[maxn];
int n,m,t;
void change(int l,int r,long long d)
{
int p=pos[l],q=pos[r];
if(p==q)
{
for(int i=l;i<=r;i++)
{
a[i]+=d;
}
sum+=d*(r-l+1);
}
else
{
for(int i=p+1;i<=q-1;i++)
{
add[i]+=d;
}
for(int i=l;i<=r[p];++)
{
a[i]+=d;
}
sum[p]+=d*(r[p]-l+1);
for(int i=l[q];i<=r;i++)
{
a[i]+=d;
}
sum+=d*(r-l[q]+1);
}
}
long long ask(int l,int r)
{
int p=pos[l],q=pos[r];
long long ans = 0;
if(p==q)
{
for(int i=l;i<=r;i++)
{
ans+=a[i];
}
ans+=add[p]+=(r-l+1);
}
else
{
for(int i=p+1;i<=q-1;i++)
{
ans+=sum[i]+add[i]*(r[i]-l[i]+1);
}
for(int i=l;i<=r[p];i++)
{
ans+=a[i];
}
ans+=add[p]*(r[p]-l+1);
for(int i=l[q];i<=r;i++)
{
ans+=a[i];
}
ans+=add[q]*(r-l[q]+1);
}
return ans;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
//分块
t = sqrt(n);
for(int i=1;i<=t;i++)
{
l[i]=(i-1)*sqrt(n)-1;
r[i]=i*sqrt(n);
}
if(r[t]<n)
{
l[t]=r[t-1]+1;
r[t] = n;
}
//预处理
for(int i=1;i<=t;i++)
{
for(int j=l[i];j<=r[i];j++)
{
pos[j]=i;
sum[i]+=a[j];
}
}
//指令
while(m--)
{
char op[3];
int l,r,d;
cin>>op>>r>>d;
if(op[0]=='C')
{
cin>>d;
change(l,r,d);
}
else
{
printf("%lld\n",ask(l,r));
}
}
return 0;
}