1 // luogu-judger-enable-o2 2 #include <cstdio> 3 using namespace std; 4 const int N=1e5+5; 5 long long tree[4*N],a[N],m,n,x,y,z,d,lazy[4*N];//一般数组开成数据范围N的4倍 6 void pushdown(int P,int l,int r)//lazy标记下传 7 { 8 int mid=(l+r)>>1; 9 tree[P*2]+=(mid-l+1)*lazy[P]; 10 lazy[P*2]+=lazy[P]; 11 tree[P*2+1]+=(r-mid)*lazy[P]; 12 lazy[P*2+1]+=lazy[P]; 13 lazy[P]=0; 14 } 15 void buildtree(int P,/*编号*/int l,/*左*/int r/*右*/)//对于节点编号P两个子节点编为P*2,P*2+1 16 { 17 if(l==r) {tree[P]=a[l]; return ;} 18 int mid=(l+r)/2; 19 buildtree(P*2,l,mid); 20 buildtree(P*2+1,mid+1,r); 21 tree[P]=tree[P*2]+tree[P*2+1]; 22 }//建树 已理解 23 void modifytree(int P,int l,int r,int ll,int rr,int x)//ll到rr加上x ;ll r为被修改区间的左右端点 24 { 25 if(l==ll&&r==rr) {tree[P]+=x*(r-l+1);lazy[P]+=x;/*lazy标记*/ return;} 26 pushdown(P,l,r); 27 int mid=(l+r)/2; 28 if(ll>mid) modifytree(P*2+1,mid+1,r,ll,rr,x); 29 else if(mid>=rr) modifytree(P*2,l,mid,ll,rr,x); 30 else modifytree(P*2,l,mid,ll,mid,x),modifytree(P*2+1,mid+1,r,mid+1,rr,x); 31 tree[P]=tree[P*2]+tree[P*2+1]; 32 } 33 long long asktree/*询问*/(int P,int l,int r,int askl,int askr) 34 //在编号为P,范围是l到r的线段中,找到askl到askr这一段 35 { 36 int mid=(l+r)/2; 37 if(l==askl && r==askr) return tree[P]; 38 if(lazy[P]!=0) { 39 pushdown(P,l,r);} 40 41 if(mid>=askr) return asktree(P*2,l,mid,askl,askr) ; 42 else if(mid<askl) return asktree(P*2+1,mid+1,r,askl,askr); 43 return asktree(P*2,l,mid,askl,mid)+asktree(P*2+1,mid+1,r,mid+1,askr); 44 45 } 46 int main() 47 { 48 scanf("%lld %lld",&n,&m); 49 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 50 buildtree(1,1,n); 51 //scanf("%d",&m); 52 for(int i=1;i<=m;i++) 53 { 54 scanf("%lld",&x); 55 if(x==1) scanf("%lld %lld %lld",&y,&z,&d),modifytree(1,1,n,y,z,d); 56 if(x==2) scanf("%lld %lld",&y,&z),printf("%lld ",asktree(1,1,n,y,z)); 57 } 58 return 0; 59 }