【线段树】区间修改区间求和

蒟蒻在线段树的路上继续前进,lazy的出题人的奇思妙想——延迟标记震撼了他。。

线段树模板题(二)——区间修改与查询区间和:区间修改区间求和 

【题目描述】  

如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.求出某区间每一个数的和

【输入】

第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

【输出】

输出包含若干行整数,即为所有操作2的结果。

【样例输入】

5 5

1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4                                                  

【样例输出】

11

8

20

 

代码:

#include
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
long long n,m,a[100010]; 
struct node{
	int l,r,lazy;//延迟标记——lazy
	long long sum; 
}T[100010*4];
void pushnow(long long p,long long v){
	T[p].sum+=(T[p].r-T[p].l+1)*v;
	T[p].lazy+=v;
} 
void pushdown(long long p){
	if(T[p].lazy){
		pushnow(lc,T[p].lazy);
		pushnow(rc,T[p].lazy);
		T[p].lazy=0;
	}
}
void pushup(long long p){
	T[p].sum=T[lc].sum+T[rc].sum;
}
void build(long long p,long long l,long long r){//建树 
	T[p].l=l;
	T[p].r=r;
	if(l==r){
		T[p].sum=a[l];
		T[p].lazy=0;
		return ;
	}
	long long mid=(l+r)>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(p); 
}
void update(long long p,long long ql,long long qr,long long v){//向上维护 
	if(ql<=T[p].l&&T[p].r<=qr){
		pushnow(p,v);
		return ;
	}
	long long mid=(T[p].l+T[p].r)>>1;
	pushdown(p);
	if(ql<=mid)
		update(lc,ql,qr,v);
	if(qr>mid)
		update(rc,ql,qr,v);
	pushup(p);
} 
long long query(long long p,long long ql,long qr){//区间求和 
	if(ql<=T[p].l&&qr>=T[p].r)
		return T[p].sum;
	long long mid=(T[p].l+T[p].r)>>1;
	pushdown(p);
	long long ans=0;
	if(ql<=mid)
		ans+=query(lc,ql,qr);
	if(qr>mid)
		ans+=query(rc,ql,qr);
	pushup(p);
	return ans; 
} 
int main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	build(1,1,100100);
	for(long long i=1;i<=m;i++){
		long long p;
		scanf("%lld",&p);
		if(p==1){
			long long x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			update(1,x,y,k);
		}
		if(p==2){
			long long x,y;
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query(1,x,y));
		}
	} 
	return 0; 
} 

 

你可能感兴趣的:(线段树,数据结构)