POJ 3468 Simple Problem with Integers

还是简单的线段树区间更新

#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
#define maxn 111111
using namespace std;
LL sum[maxn<<2],lazy[maxn<<2];

int max(int x,int y){
	if (x>y) return x;
	else return y;
}
int min(int x,int y){
	if (x<y) return x;
	else return y;
}
void pushup(int rt){
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int rt,int m){
	if (lazy[rt]) {
		lazy[rt<<1]+=lazy[rt];
		lazy[rt<<1|1]+=lazy[rt];
		sum[rt<<1]+=lazy[rt]*(m-(m>>1));
		sum[rt<<1|1]+=lazy[rt]*(m>>1);
		lazy[rt]=0;
	}
}
void build(int l,int r,int rt){
	lazy[rt]=0;
	if (l==r) {
		scanf("%lld",&sum[rt]);
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
	pushup(rt);
}

void update(int L,int R,int c,int l,int r,int rt){
	if (L<=l && r<=R) {
		lazy[rt]+=c;
		sum[rt]+=(LL)c*(r-l+1);
		return ;
	}
	pushdown(rt,r-l+1);
	int mid=(l+r)>>1;
    if (L<=mid) update(L,R,c,l,mid,rt<<1);
    if (mid<R) update(L,R,c,mid+1,r,rt<<1|1);
    pushup(rt);
}
LL query(int L,int R,int l,int r,int rt){
	if (L<=l && r<=R) {
		return sum[rt];
	}
	pushdown(rt,r-l+1);
	int mid=(l+r)>>1;
	LL ret=0;
	if (L<=mid) ret+=query(L,R,l,mid,rt<<1);
	if (mid<R) ret+=query(L,R,mid+1,r,rt<<1|1);
	return ret;

}
int main(){
	int N,Q;
	scanf("%d%d",&N,&Q);
	build(1,N,1);
	while (Q--){
		char op[2];
		int a,b,c;
		scanf("%s",op);
		if (op[0]=='Q') {
			scanf("%d%d",&a,&b);
			printf("%lld\n",query(a,b,1,N,1));
		}
		else {
			scanf("%d%d%d",&a,&b,&c);
			update(a,b,c,1,N,1);
		}
	}
	return 0;
}


你可能感兴趣的:(POJ 3468 Simple Problem with Integers)