线段树——线段树1(求和)
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
const int N=1e5+114;
int n,m;
int s[N];
struct node{int l,r,val,lazy;
}tree[2*N];
void build(int l,int r,int num){tree[num].l=l;tree[num].r=r;if(l==r){tree[num].val=s[l];return;}int mid=l+(r-l)/2;build(l,mid,2*num);build(mid+1,r,2*num+1);tree[num].val=tree[2*num].val+tree[2*num+1].val;return;
}
int getsum(int tarl,int tarr,int num){if(tree[num].l>=tarl&&tree[num].r<=tarr)return tree[num].val+tree[num].lazy*(tree[num].r-tree[num].l+1);if(tree[num].r<tarl||tree[num].l>tarr)return 0;if(tree[num].lazy){tree[num].val+=tree[num].lazy*(tree[num].r-tree[num].l+1);tree[2*num].lazy+=tree[num].lazy;tree[2*num+1].lazy+=tree[num].lazy;tree[num].lazy=0;}int ans=0;ans+=getsum(tarl,tarr,2*num);ans+=getsum(tarl,tarr,2*num+1);return ans;
}
void add(int tarl,int tarr,int num,int plus){if(tree[num].l>=tarl&&tree[num].r<=tarr){tree[num].lazy+=plus;return;}if(tree[num].r<tarl||tree[num].l>tarr)return;if(tree[num].lazy!=0){tree[2*num].lazy+=tree[num].lazy;tree[2*num+1].lazy+=tree[num].lazy;tree[num].val+=tree[num].lazy*(tree[num].r-tree[num].l+1);tree[num].lazy=0;}tree[num].val+=plus*(min(tree[num].r,tarr)-max(tree[num].l,tarl)+1);add(tarl,tarr,2*num,plus);add(tarl,tarr,2*num+1,plus);return;
}
signed main(){IOScin>>n>>m;for(int i=1;i<=n;i++)cin>>s[i];build(1,n,1);while(m--){int which;cin>>which;if(which==1){int l,r,plus;cin>>l>>r>>plus;add(l,r,1,plus);}else {int l,r;cin>>l>>r;cout<<getsum(l,r,1)<<endl;}}return 0;
}