分块:
将分块区间更改,原数组更改,累加求和,时间复杂
O(sqrt(n))
AC代码:
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
const ll maxn=1e5+5;
ll a[maxn],pos[maxn],sum[maxn],l[maxn],r[maxn],lazy[maxn];
void modify(ll lx,ll rx,ll w)
{
ll blc=pos[lx];
ll blk=pos[rx];
if(blc==blk)
{
for(ll i=lx;i<=rx;i++)
{
a[i]+=w;
}
sum[blc]+=(rx+1-lx)*w;
}
else
{
for(ll i=lx;i<=r[blc];i++)
{
a[i]+=w;
}
sum[blc]+=(r[blc]+1-lx)*w;
for(ll i=blc+1;i<=blk-1;i++)
{
lazy[i]+=w;
}
for(ll i=l[blk];i<=rx;i++)
{
a[i]+=w;
}
sum[blk]+=(rx+1-l[blk])*w;
}
}
ll query(ll lx,ll rx)
{
ll blc=pos[lx];
ll blk=pos[rx];
ll res=0;
if(blc==blk)
{
for(ll i=lx;i<=rx;i++)
{
res+=a[i];
}
res+=(rx+1-lx)*lazy[blc];
}
else
{
for(ll i=lx;i<=r[blc];i++)
{
res+=a[i];
}
res+=(r[blc]-lx+1)*lazy[blc];
for(ll i=blc+1;i<=blk-1;i++)
{
res+=(sum[i]+(r[i]+1-l[i])*lazy[i]);
}
for(ll i=l[blk];i<=rx;i++)
{
res+=a[i];
}
res+=(rx+1-l[blk])*lazy[blk];
}
return res;
}
int main()
{
ll n,q;
scanf("%lld %lld",&n,&q);
ll dis=sqrt(n);
ll num=ceil(n*1.0/dis);
for(ll i=1;i<=num;i++)
{
l[i]=(i-1)*dis+1;
r[i]=i*dis;
}
r[num]=n;
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
pos[i]=(i-1)/dis+1;
sum[pos[i]]+=a[i];
}
while(q--)
{
char s[5];
ll lx,rx,w;
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%lld %lld",&lx,&rx);
printf("%lld\n",query(lx,rx));
}
else
{
scanf("%lld %lld %lld",&lx,&rx,&w);
modify(lx,rx,w);
}
}
}