飘过的小牛

I'm growing!~~

Hdu-1166 敌兵布阵【线段树(单点更新)】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

解题思路:

线段树的入门题,可以用谷歌搜索线段树或者segment tree,理解后就可以了。

我采用的是静态建树。


代码如下:

#include<cstdio>

#define lson l, m, root << 1
#define rson m + 1, r, root << 1 | 1
const int N = 50005;
int segtree[N << 2]; //开4倍

void PushUp(int root) //向上更新
{
	segtree[root] = segtree[root << 1] + segtree[root << 1 | 1];
}

void Build_Tree(int l, int r, int root) //递归建立二叉树
{
	if(l == r)
	{
		scanf("%d", &segtree[root]);
		return ;
	}
	int m = (l + r) >> 1;
	Build_Tree(lson);
	Build_Tree(rson);
	PushUp(root);
}

void Update(int pos, int data, int l, int r, int root) //插点
{
	if(l == r)
	{
		segtree[root] += data;
		return ;
	}
	int m = (l + r) >> 1;
	if(pos <= m) Update(pos, data, lson);
	else Update(pos, data, rson);
	PushUp(root);
}

int Query(int L, int R, int l, int r, int root) //查找
{
	int sum = 0;
	if(L <= l && r <= R) //查询线段包含线段树节点线段
		return segtree[root];
	int m = (l + r) >> 1;
	if(L <= m)
		sum += Query(L, R, lson);
	if(R > m)
		sum += Query(L, R, rson);
	return sum;
}

int main()
{
	int ncase;
	int num;
	char ope[10];
	int a, b;
	scanf("%d", &ncase);
	for(int i = 1; i <= ncase; ++i)
	{
		printf("Case %d:\n", i);
		scanf("%d", &num);
		Build_Tree(1, num, 1);
		while(~scanf("%s", ope))
		{
			if(ope[0] == 'E')
				break;
			scanf("%d %d", &a, &b);
			if(ope[0] == 'A')
				Update(a, b, 1, num, 1);
			else if(ope[0] == 'S')
				Update(a, -b, 1, num, 1);
			else
				printf("%d\n", Query(a, b, 1, num, 1));
		}
	}
	return 0;
}


阅读更多
文章标签: tree query build
个人分类: 线段树/树状数组
上一篇POJ-2352 Stars【树状数组】
下一篇ubuntu最常用的10个快捷键
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭