https://www.luogu.com.cn/problem/P3373
orz
#include <bits/stdc++.h>
using namespace std;
int n,m;
const int maxn = 1e5 + 1;
long long a[maxn] = {}, tree[maxn*4] = {}, lazy[maxn*4] = {};
inline void buildTree(int s, int t, int node){
int left = 2*node, right = 2*node + 1, mid = (s + t)/2;
if(s == t) {
tree[node] = a[s];
return ;
}
buildTree(s,mid,right);
buildTree(mid+1,t,left);
tree[node] = tree[left] + tree[right];
}
void pushDown(int left, int right, int node, int s, int t, int mid){
if(lazy[node]){
long long k = lazy[node];
lazy[node] = 0;
tree[left] += (mid - s + 1)*k; lazy[left] += k;
tree[right] += (t - mid)*k; lazy[right] += k;
}
}
void update(int l, int r, long long k, int s, int t, int node){
int left = 2*node, right = 2*node + 1, mid = (s + t)/2;
if(l <= s && t <= r) {
tree[node] += k*(t-s+1);
lazy[node] += k;
return;
}
pushDown(left, right, node, s, t, mid);
if(l <= mid) update(l,r,k,s,mid,left);
if(r > mid) update(l,r,k,mid+1,t,right);
tree[node] = tree[left] + tree[right];
}
long long getsum(int l, int r, int s, int t, int node){
int left = node*2, right = node*2+1, mid = (s + t)/2;
if(l <= s && t <= r){
return tree[node];
}
pushDown(left,right,node,s,t,mid);
long long sum = 0;
if(l <= mid) sum += getsum(l,r,s,mid,left);
if(r > mid) sum += getsum(l,r,mid+1,t,right);
return sum;
}
int main(){
cin>>n>>m;
for(int i = 1; i <= n; ++i) cin>>a[i];
buildTree(1,n,1);
do{
int t;
cin>>t;
if(t == 1) {
int x,y; long long k;
cin>>x>>y>>k;
update(x,y,k,1,n,1);
}
if(t == 2){
int x,y;
cin>>x>>y;
cout<<getsum(x,y,1,n,1)<<'\n';
}
}while(--m);
return 0;
}