code:(洛谷P3372)
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<ctime>
using namespace std;
const int MAX=100010;
const int INF=0x3f3f3f3f;
int n,m;
long long a[MAX];
struct nodes{
long long sum,lazy;
}node[MAX<<1+1];
void pushup(int cur){
node[cur].sum=node[cur<<1].sum+node[cur<<1|1].sum;
}
void pushdown(int cur,int ln,int rn){
if(node[cur].lazy){
int c=node[cur].lazy;
node[cur<<1].sum+=c*ln;
node[cur<<1].lazy+=c;
node[cur<<1|1].sum+=c*rn;
node[cur<<1|1].lazy+=c;
node[cur].lazy=0;
}
}
void build(int l,int r,int cur){
if(l==r) {
node[cur].sum=a[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
pushup(cur);
}
void edge_update(int L,int R,int c,int l,int r,int cur){
if(l>=L&&r<=R) {
node[cur].sum+=c*(r-l+1);
node[cur].lazy+=c;
return ;
}
int mid=(l+r)>>1;
pushdown(cur,mid-l+1,r-mid);
if(L<=mid) edge_update(L,R,c,l,mid,cur<<1);
if(R>mid) edge_update(L,R,c,mid+1,r,cur<<1|1);
pushup(cur);
}
void point_update(int L,long long c,int l,int r,int cur){
if(l==r) {
node[cur].sum+=c;
return ;
}
int mid=(l+r)>>1;
if(L>mid) point_update(L,c,mid+1,r,cur<<1|1);
else point_update(L,c,l,mid,cur<<1);
pushup(cur);
}
long long query(int L,int R,int l,int r,int cur){
if(L<=l&&R>=r) return node[cur].sum;
int mid=(l+r)>>1;
pushdown(cur,mid-l+1,r-mid);
long long ans=0;
if(L<=mid) ans+=query(L,R,l,mid,cur<<1);
if(R>mid) ans+=query(L,R,mid+1,r,cur<<1|1);
return ans;
}
void print(){
cout<<endl;
for(int i=1;i<=n*2;i++)
printf("%d ",node[i].sum);
cout<<endl<<endl;;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
// print();
for(int i=1;i<=m;i++) {
int c,x,y;
scanf("%d",&c);
if(c==1) {
long long k;
scanf("%d %d %lld",&x,&y,&k);
edge_update(x,y,k,1,n,1);
// print();
}
if(c==2) {
scanf("%d %d",&x,&y);
printf("%lld
",query(x,y,1,n,1));
}
}
return 0;
}