线段树模板
看题目戳这多打几遍就好了
记住define后面不能加分号aaaaa
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node{
int l,r;
ll sum,add;
#define sum(x) tree[x].sum
#define add(x) tree[x].add
#define l(x) tree[x].l
#define r(x) tree[x].r
}tree[100005*4];
int a[100005];
void build(int p,int l,int r){
l(p)=l;
r(p)=r;
if(l==r){
sum(p)=a[l];
return;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
sum(p)=sum(p*2)+sum(p*2+1);
}
void spread(int p){
if(add(p)){
sum(2*p)+=add(p)*(r(2*p)-l(2*p)+1);
sum(2*p+1)+=add(p)*(r(2*p+1)-l(2*p+1)+1);
add(2*p)+=add(p);
add(2*p+1)+=add(p);
add(p)=0;
}
}
void change(int p,int l,int r,int d){
if(l<=l(p)&&r(p)<=r){
add(p)+=d;
sum(p)+=(ll)d*(r(p)-l(p)+1);
return;
}
spread(p);
int mid=(l(p)+r(p))>>1;
if(mid>=l){
change(p*2,l,r,d);
}
if(mid<r){
change(p*2+1,l,r,d);
}
sum(p)=sum(p*2)+sum(p*2+1);
}
ll ask(int p,int l,int r){
if(l<=l(p)&&r(p)<=r){
return sum(p);
}
spread(p);
int mid=(l(p)+r(p))>>1;
ll val=0;
if(mid>=l){
val+=ask(2*p,l,r);
}
if(mid<r){
val+=ask(2*p+1,l,r);
}
return val;
}
int main(){
int n,m,val,l,r,op;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,1,n);
for(int i=0;i<m;i++){
scanf("%d%d%d",&op,&l,&r);
if(op==1){
scanf("%d",&val);
change(1,l,r,val);
}else {
printf("%lld\n",ask(1,l,r));
}
}
return 0;
}