线段树成段更新的模板

#include <iostream>
#include <cstdio>

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int maxx=100002;

struct{
    __int64 sum;
    int col;
}Tree[maxx<<2];

void pushUp(__int64 rt){
	Tree[rt].sum=Tree[rt<<1].sum+Tree[rt<<1|1].sum;
}

void build(int l,int r,int rt){
	Tree[rt].col=0;
	if(l==r){
		scanf("%I64d",&Tree[rt].sum);//刚开始这地方输入忘记了是六十四位整数输入  wa了两次
		return ;
	}
	int m=(l+r)>>1;
	build(lson);
	build(rson);
	pushUp(rt);
}

void pushDown(int rt,int m){
	if(Tree[rt].col){
		Tree[rt<<1].col+=Tree[rt].col;//以下都为在原有的基础上增加
		Tree[rt<<1|1].col+=Tree[rt].col;
		Tree[rt<<1].sum+=(__int64)Tree[rt].col*(m-(m>>1));
		Tree[rt<<1|1].sum+=(__int64)Tree[rt].col*(m>>1);
		Tree[rt].col=0;
	}
}

void update(int L,int R,int c,int l,int r,int rt){
	if(L<=l && r<=R){
		Tree[rt].sum+=(r-l+1)*(__int64)c;
		Tree[rt].col+=c;
		return ;
	}
	pushDown(rt,r-l+1);
	int m=(l+r)>>1;
	if(L<=m)update(L,R,c,lson);
	if(R>m)update(L,R,c,rson);
	pushUp(rt);
}

__int64 query(int L,int R,int l,int r,int rt){
	if(L<=l && r<=R){
		return Tree[rt].sum;
	}
	pushDown(rt,r-l+1);
	int m=(l+r)>>1;
	__int64 ret=0;
	if(L<=m)ret+=query(L,R,lson);
	if(R>m)ret+=query(L,R,rson);
	return ret;
}

int main(){
	int n,o;
	scanf("%d%d",&n,&o);
	build(1,n,1);
	while(o--){
		char op[3];
		int x,y,c;
		scanf("%s",op);
		if(op[0]=='Q'){
			scanf("%d%d",&x,&y);
			printf("%I64d\n",query(x,y,1,n,1));
		}else{
			scanf("%d%d%d",&x,&y,&c);
			update(x,y,c,1,n,1);
		}
	}
	return 0;
}

http://poj.org/problem?id=3468

你可能感兴趣的:(线段树成段更新的模板)