mincrafter_or_cy @ 2024-07-22 21:01:43
#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
long long n;
long long a[maxn],sum[maxn<<2]/*和*/,b[maxn<<2]/*标记*/;
void build(long long l,long long r,long long p){//堆式建树
if(l==r){sum[p]=a[l];return;} //将节点赋值
long long m=l+((r-l)>>1);
build(l,m,p<<1);
build(m+1,r,(p<<1)|1l); //分别建立子树
sum[p]=sum[p<<1]+sum[(p<<1)|1l];
}
void pushdown(long long p,long long s,long long t){
if(b[p]==0) return;
long long m=s+((s-t)>>1);
sum[p<<1]+=b[p]*(m-s+1l);
sum[(p<<1)|1]+=b[p]*(t-m);
b[p<<1]+=b[p];
b[(p<<1)|1l]+=b[p];
b[p]=0;
}
void update(long long l,long long r,long long c,long long s,long long t,long long p){
if(l<=s&&t<=r){sum[p]+=(t-s+1l)*c;b[p]+=c;return;} //区间被包含
long long m=s+((t-s)>>1);
pushdown(p,s,t);
if(l<=m) update(l,r,c,s,m,p<<1);//本行和下面的一行用来更新p*2和p*2+1的节点
if(r>m) update(l,r,c,m+1,t,(p<<1)|1l);
sum[p]=sum[p<<1]+sum[(p<<1)|1l]; //计算该节点区间
}
long long getsum(long long l,long long r,long long s,long long t,long long p) {
if(l<=s&&t<=r) return sum[p];
long long m=s+((t-s)>>1);
pushdown(p,s,t);
long long ans=0;
if(l<=m) ans=getsum(l,r,s,m,p<<1);//本行和下面的一行用来获取p*2和p*2+1的答案
if(r>m) ans+=getsum(l,r,m+1,t,(p<<1)|1l);
return ans;
}
int main(){
long long q,type,x,y,k;
scanf("%lld%lld",&n,&q);
for(long long i=1l;i<=n;i++)
scanf("%lld",&a[i]);
build(1l,n,1l);
for(;q;q--){
scanf("%lld%lld%lld",&type,&x,&y);
if(type==2) printf("%lld\n",getsum(x,y,1l,n,1l));
else{scanf("%lld",&k);update(x,y,k,1l,n,1l);}
}
return 0;
}
by W_Galaxy @ 2024-07-22 21:24:46
第15行是
long long m=s+((t-s)>>1);