洛谷P3372
传送门
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e6+7;
int a[maxn];
struct node{
int l,r;
long long lazy,sum;
void update(long long v){
sum += 1ll*v*(r-l+1);
lazy +=v;
}
}tree[maxn*4];
void push_up(int x){
tree[x].sum = tree[x<<1].sum + tree[x<<1|1].sum;
}
void push_down(int x){
long long lazyval = tree[x].lazy;
if(lazyval){
tree[x<<1].update(lazyval);
tree[x<<1|1].update(lazyval);
tree[x].lazy = 0;
}
}
inline void update(int x,int l,int r,long long v){
int L = tree[x].l,R = tree[x].r;
if(l<=L&&R<=r){
tree[x].update(v);
}
else{
push_down(x);
int mid = (L+R)>>1;
if(mid>=l) update(x<<1,l,mid,v);
if(mid<r) update(x<<1|1,mid+1,r,v);
push_up(x);
}
}
inline long long query(int x,int l,int r){
int L = tree[x].l,R = tree[x].r;
if(l<=L&&R<=r){
return tree[x].sum;
}
else{
int ans = 0;
push_down(x);
int mid = (L+R)>>1;
if(mid>=l) ans += query(x<<1,l,mid);
if(mid<r) ans += query(x<<1|1,mid+1,r);
return ans;
}
}
inline void build(int x,int l,int r){
tree[x].l = l,tree[x].r = r;
tree[x].sum = tree[x].lazy = 0;
if(l == r){
tree[x].sum = a[l];
}
else{
int mid = (l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
push_up(x);
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
//init
memset(tree,0,sizeof(tree));
build(1,1,n);
int l,r,q;
long long val;
for(int i=1;i<=m;i++){
cin>>q;
if(q == 1){
cin>>l>>r>>val;
update(1,l,r,val);
}
else{
cin>>l>>r;
//printf("%lld\n",query(1,l,r));
cout<<query(1,l,r)<<endl;
}
}
return 0;
}