rt,我用线段树维护差分
#include<bits/stdc++.h>
#define int long long
#define left node<<1
#define right node<<1|1
using namespace std;
int tree[5000050],arr[500050],kp[500050];
void build(int l,int r,int node) {
if(l==r) {
tree[node]=arr[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,left);
build(mid+1,r,right);
tree[node]=tree[left]+tree[right];
}
void update(int l,int r,int node,int idx,int newval) {
if(l==r) {
tree[node]+=newval;
return;
}
int mid=(l+r)>>1;
if(idx<=mid)
update(l,mid,left,idx,newval);
else
update(mid+1,r,right,idx,newval);
tree[node]+=newval;
}
int query(int node,int s,int e,int l,int r) {
if(r<s||e<l)
return 0;
if(s==e||(l<=s&&e<=r))
return tree[node];
int mid=(s+e)>>1;
return query(left,s,mid,l,r)+query(right,mid+1,e,l,r);
}
int n,m,k,x,y;
signed main() {
//freopen("tree.in","r",stdin);
//freopen("tree.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1; i<=n; ++i) {
cin>>kp[i];
arr[i]=kp[i]-kp[i-1];
}
build(1,n,1);
while(m--) {
cin>>k;
if(k==1) {
cin>>x>>y>>k;
update(1,n,1,x,k);
update(1,n,1,y+1,-k);
} else {
cin>>x>>y;
cout<<query(1,1,n,1,y)-query(1,1,n,1,x-1)<<endl;
}
}
}