分块的思路 从网上遇到大佬的思路
添加了一个bl数组用于sum数组的下标
三层for走左快 中间的 右快 思路比较简单好写
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
#define hengheng main()
#define mem(a,b) memset(a,b,sizeof(a))
const int maxx =1e6+10;
int k;
int a[maxx];char ch[3];
ll block[maxx];
ll sum[maxx];
ll bl[maxx];
ll atag[maxx];
void addd(ll l, ll r, ll add,int k)
{
int mi = min(r, bl[l]*k);
for(int i = l; i <= mi; i++) a[i] += add, sum[bl[i]] += add;
if(bl[l] != bl[r])
for(int i = (bl[r]-1)*k+1; i <= r; i++) a[i] += add, sum[bl[i]] += add;
for(int i = bl[l]+1; i <= bl[r]-1; i++) atag[i] += add, sum[i] += add*k;
}
ll serch(ll l,ll r,ll k)
{
ll ans=0;
int mi=min(r,bl[l]*k);
for(int i=l;i<=mi;i++) ans+=a[i]+atag[bl[i]];
if(bl[l]!=bl[r])
for(int i = (bl[r]-1)*k+1; i <= r; i++) ans += a[i]+atag[bl[i]];
for(int i = bl[l]+1; i <= bl[r]-1; i++) ans += sum[i];
return ans;
}
int main()
{
ll n,t; int l,r,add,m,i,j;
int x,y;
scanf("%lld%lld",&n,&t);
k=(sqrt(1.0*n));
for(i=1;i<=n;i++)
{
bl[i]=(i-1)/k+1;
}
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[bl[i]]+=a[i];
}
// for(i=1;i<=k;i++) printf("%lld\n",sum[i]);
while(t--)
{
scanf("%s",ch);
if(ch[0]=='Q')
{
scanf("%d%d",&l,&r);
printf("%lld\n",serch(l,r,k));
}
else
{
scanf("%d%d%d",&l,&r,&add);
addd(l,r,add,k);
}
}
return 0;
}