POJ - 3468 A Simple Problem with Integers 線段樹延遲標記模板題

題目大意

給定一個長度爲n的序列, 求m組詢問
C l r d 代表把區間l-r的數加上d
Q l r 代表求區間l, r的和

樣例

Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15

代碼

#include <iostream>
#include <cstring>
#include <iostream>
#include <cstdio>

using namespace std;
const int N = 100010;
typedef long long ll;

struct Tree{
	int l, r;
	ll sum, lazy;
};

Tree tree[N * 4];
int a[N];
int n, m;

void pushdown(int node)
{
	if(tree[node].lazy)
	{
		int l = tree[node].l;
		int r = tree[node].r;
		tree[node << 1].lazy += tree[node].lazy;
		tree[node << 1 | 1].lazy += tree[node].lazy;
		int mid = (l + r) >> 1;
		tree[node << 1].sum += tree[node].lazy * (mid - l + 1);
		tree[node << 1 | 1].sum += tree[node].lazy * (r - mid);
		tree[node].lazy = 0;
	}
}

void pushup(int node)
{
	tree[node].sum = tree[node << 1].sum + tree[node << 1 | 1].sum;
}

void build(int node, int l, int r)
{
	tree[node].l = l;
	tree[node].r = r;
	if(l == r)
	{
		tree[node].sum = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(node << 1, l, mid);
	build(node << 1 | 1, mid + 1, r);
	pushup(node);
}

void update(int node, int l, int r, int d)
{
	if(tree[node].l >= l && tree[node].r <= r)
	{
		tree[node].sum += (ll)d * (tree[node].r - tree[node].l + 1);
		tree[node].lazy += d;
		return;
	}
	int x = tree[node].l;
	int y = tree[node].r;
	int mid = (x + y) >> 1;
	pushdown(node);
	if(l <= mid)
		update(node << 1, l, r, d);
	if(r > mid)	
		update(node << 1 | 1, l, r, d);
	pushup(node);	
}

ll query(int node, int l, int r)
{
	if(tree[node].l >= l && tree[node].r <= r)
		return tree[node].sum;
	pushdown(node);
	int mid = (tree[node].l + tree[node].r) >> 1;
	ll ans = 0;
	if(l <= mid)
		ans += query(node << 1, l, r);
	if(r > mid)
		ans += query(node << 1 | 1, l, r);
	return ans;
}

int main()
{
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++)
		scanf("%d", a + i);
	build(1, 1, n);
	while(m--)
	{
		char s[2];
		int l, r;
		scanf("%s%d%d", s, &l, &r);
		if(*s == 'C')
		{
			int d;
			scanf("%d", &d);
			update(1, l, r, d);
		}
		else
			printf("%lld\n", query(1, l, r));
		
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章