线段树模板(支持区间加,区间和)

#include<bits/stdc++.h>
#define N 100010
#define lson (k<<1)
#define rson (k<<1|1)
#define mid ((l+r)>>1)
using namespace std;
namespace program{
	int Tag[N<<2],Sum[N<<2];
	template<class T>
	T read(){
		T s=0;
		int ch;
		while(!isdigit(ch=getchar()));
		do
			s=s*10+ch-'0';
		while(isdigit(ch=getchar()));
		return s;
	}
	inline void build(int l,int r,int k){
		Tag[k]=0;
		if(l==r)
			Sum[k]=read<int>();
		else{
			build(l,mid,lson);
			build(mid+1,r,rson);
			Sum[k]=Sum[lson]+Sum[rson];
		}
	}
	inline void updata(int l,int r,int x,int y,int val,int k){
		if(x<=l&&r<=y){
			Tag[k]+=val;
			Sum[k]+=(r-l+1)*val;
		}else{
			if(mid>=x)
				updata(l,mid,x,y,val,lson);
			if(mid<y)
				updata(mid+1,r,x,y,val,rson);
			Sum[k]=Sum[lson]+Sum[rson]+(r-l+1)*Tag[k];
		}
	}
	inline int query(int l,int r,int x,int y,int k){
		if(x<=l&&r<=y)
			return Sum[k];
		else{
			int tot=(min(r,y)-max(l,x)+1)*Tag[k];
			if(mid>=x)
				tot+=query(l,mid,x,y,lson);
			if(mid<y)
				tot+=query(mid+1,r,x,y,rson);
			return tot;
		}
	}
	inline void work(){
		int n,m,l,r,val;
		cin>>n>>m;
		build(1,n,1);
		for(int i=1;i<=m;i++){
			if(read<int>()==1){
				l=read<int>();
				r=read<int>();
				val=read<int>();
				updata(1,n,l,r,val,1);
			}else{
				l=read<int>();
				r=read<int>();
				cout<<query(1,n,l,r,1)<<'\n';
			}
		}
	}
}
int main(){
	program::work();
	return 0;
}


阅读更多
换一批

没有更多推荐了,返回首页