您的位置:首页 > 其它

POJ - 3468 A Simple Problem with Integers(线段树成段更新,查询区间和)

2015-09-24 03:13 429 查看
A Simple Problem with Integers

Time Limit: 5000MSMemory Limit: 131072KB64bit IO Format: %I64d & %I64u
Submit Status

Description

给出了一个序列,你需要处理如下两种询问。

"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。

"Q a b" 询问[a, b]区间中所有值的和。

Input

第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.

第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。

接下来Q行询问,格式如题目描述。

Output

对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。

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 <cstdio>
#include<cstring>
using namespace std;

#define LL long long
#define max(a,b) a>b?a:b
const LL MAXN = 200000 + 1000;

LL num[MAXN];
LL father[MAXN];
LL anssum;

struct node
{
	LL l, r;
	LL Sum;
	LL lazy;
}tree[MAXN * 3];

inline void pushUp(LL i)
{
	LL ls = i << 1, rs = ls + 1;
	tree[i].Sum = tree[ls].Sum + tree[rs].Sum;
}

void pushDown(LL i)
{
	LL ls = i << 1, rs = ls + 1;
	tree[ls].lazy += tree[i].lazy;
	tree[rs].lazy += tree[i].lazy;
	tree[ls].Sum += tree[i].lazy*(tree[ls].r - tree[ls].l + 1);
	tree[rs].Sum += tree[i].lazy*(tree[rs].r - tree[rs].l + 1);
	tree[i].lazy = 0;
}

void build(LL l, LL r, LL i)
{
	tree[i].lazy = 0;
	tree[i].l = l;
	tree[i].r = r;
	if (l == r)
	{
		tree[i].Sum = num[l];
		father[l] = i;
		return;
	}
	LL ls = i << 1, rs = ls + 1;
	LL m = (l + r) >> 1;
	build(l, m, ls);
	build(m + 1, r, rs);
	pushUp(i);
}

void update(LL l, LL r, LL i, LL v)
{
	if (l <= tree[i].l && r >= tree[i].r)
	{
		tree[i].lazy += v;
		tree[i].Sum += v*(tree[i].r - tree[i].l + 1);
		return;
	}
	if (tree[i].lazy)
		pushDown(i);

	LL m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1;

	if(l<=m) update(l, r, ls, v);
	if(r>m) update(l, r, rs, v);

	pushUp(i);
}

void query(LL l, LL r, LL i)
{
	if (l <= tree[i].l && r >= tree[i].r)
	{
		anssum += tree[i].Sum;
		return;
	}
	if (tree[i].lazy)
		pushDown(i);
	LL m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1;
	if (l <= m)
		query(l, r, ls);
	if (r > m)
		query(l, r, rs);
}

int main()
{
	LL n, q;
	scanf("%I64d %I64d", &n, &q);
	for (LL i = 1; i <= n; i++)
		scanf("%I64d", &num[i]);
	build(1, n, 1);
	char op;
	LL a, b, c;
	while (q--)
	{
		cin >> op;
		if (op == 'C')
		{
			scanf("%I64d %I64d %I64d", &a, &b, &c);
			update(a, b, 1, c);
		}
		else
		{
			scanf("%I64d %I64d", &a, &b);
			anssum = 0;
			query(a, b, 1);
			printf("%I64d\n", anssum);
		}
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: