poj3468 A Simple Problem with Integers(线段树,区间更新,区间和查询)

题目链接:http://poj.org/problem?id=3468


题意:

给出n个数,有q个操作,其中一种操作是将某个区间都加上某一个整数,另一个操作是询问某个区间的和。


思路:

线段树,区间更新,区间和查询。区间更新自然用到lazy-tag。模板题,关键还是理解模板。


注意数据范围


代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
typedef long long LL;

using namespace std;
const int maxn = 100000;

LL add[4*maxn+5];
LL sum[4*maxn+5];


void up(int rt){
	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
	return;
}

void down(int rt, int m){
	if(add[rt]){
		add[rt<<1] += add[rt];
		add[rt<<1|1] += add[rt];
		sum[rt<<1] += (m-(m>>1))*add[rt];
		sum[rt<<1|1] += (m>>1)*add[rt];
		add[rt] = 0;
	}
	return;
}

void build(int rt, int l, int r){
	if(l==r){
		scanf("%lld", &sum[rt]);
	}
	else{
		int mid = (l+r)>>1;
		build(rt<<1, l, mid);
		build(rt<<1|1, mid+1, r);
		up(rt);
	}
	return;
}

void update(int val, int rt, int l, int r, int x, int y){
	if(x<=l && r<=y){
		sum[rt] += (LL)(val*(r-l+1));
		add[rt] += val;
	}
	else{
		down(rt, r-l+1);
		int mid = (l+r)>>1;
		if(x<=mid) update(val, rt<<1, l, mid, x, y);
		if(y>mid) update(val, rt<<1|1, mid+1, r, x, y);
		up(rt);
	}
	return;
}

LL query(int rt, int l, int r, int x, int y){
	if(x<=l && r<=y){
		return sum[rt];
	}
	else{
		down(rt, r-l+1);
		int mid = (l+r)>>1;
		LL ans = 0;
		if(x<=mid) ans += query(rt<<1, l, mid, x, y);
		if(y>mid) ans += query(rt<<1|1, mid+1, r, x, y);
		return ans;
	}
}



int main(){
	char operat;
	int n, q;
	LL a, b, c;
	while(scanf("%d%d", &n, &q)!=EOF){
        memset(sum, 0, sizeof(sum));
        memset(add, 0, sizeof(add));

		build(1, 1, n);

		for(int i=0; i<q; i++){
            getchar();
			scanf("%c", &operat);
			if(operat=='C'){
				scanf("%lld%lld%lld", &a, &b, &c);
				update(c, 1, 1, n, a, b);
			}
			else{
				scanf("%lld%lld", &a, &b);
				printf("%lld\n", query(1, 1, n, a, b));
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值