SegmentTree_2 ( PushDown )

#include<cstdio>
#define int long long
#define MAXN 100005

int n,m,c[MAXN<<2],add[MAXN<<2],a[MAXN];

inline void pushdown(int k,int l,int r){
	if(!add[k])return;
	int mid=(l+r)>>1;
	add[k<<1]+=add[k];
	c[k<<1]+=add[k]*(mid-l+1);
	add[k<<1|1]+=add[k];
	c[k<<1|1]+=add[k]*(r-mid);
	add[k]=0;
}

inline void build(int k,int l,int r){
	if(l==r){
		c[k]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	c[k]=c[k<<1]+c[k<<1|1];
}

inline void modify(int k,int l,int r,int xl,int xr,int x){
	if(xl<=l&&r<=xr){
		c[k]+=(r-l+1)*x;
		add[k]+=x;
		return;
	}
	pushdown(k,l,r);
	int mid=(l+r)>>1;
	if(xl<=mid)modify(k<<1,l,mid,xl,xr,x);
	if(xr>=mid+1)modify(k<<1|1,mid+1,r,xl,xr,x);
	c[k]=c[k<<1]+c[k<<1|1];
}

inline int query(int k,int l,int r,int xl,int xr){
	if(xl<=l&&r<=xr){
		return c[k];
	}
	pushdown(k,l,r);
	int mid=(l+r)>>1,qvq=0;
	if(xl<=mid)qvq+=query(k<<1,l,mid,xl,xr);
	if(xr>=mid+1)qvq+=query(k<<1|1,mid+1,r,xl,xr);
	return qvq;
}

signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt;
		scanf("%lld",&opt);
		if(opt-1){
			int x,y;
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query(1,1,n,x,y));
		}
		else {
			int x,y,z;
			scanf("%lld%lld%lld",&x,&y,&z);
			modify(1,1,n,x,y,z);
		}
	}
}
posted @ 2019-10-26 20:57  Y15BeTa  阅读(111)  评论(0编辑  收藏  举报