关闭

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

标签: treequerybuild
1406人阅读 评论(0) 收藏 举报
分类:

题目链接: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;
}


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    座右铭:
    时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面……
    没有谁生来就是神牛,而千里之行,始于足下!
    个人资料
    • 访问:1848989次
    • 积分:18050
    • 等级:
    • 排名:第536名
    • 原创:317篇
    • 转载:51篇
    • 译文:0篇
    • 评论:590条
    最新评论