hdu 1166线段树

线段树的一般模板,1.结构体数组tree来存储  2.线段树的构建函数buildTree  3.改变元素值函数update   4.查询区间内总和的函数query
全部使用递归来实现

#####################################################################
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>

using namespace std;

const int maxn = 50050;
int ans;

struct node{
	int left, right, sum;
	int mid(){
		return (left+right)/2;
	}
}tree[maxn*4];

void buildTree(int left, int right, int rt)
{
	tree[rt].left = left;
	tree[rt].right = right;
	if(left == right){
		cin >> tree[rt].sum;
		return ;
	}
	int mid = tree[rt].mid();
	buildTree(left, mid, rt*2);
	buildTree(mid+1, right, rt*2+1);
	tree[rt].sum = tree[rt*2].sum + tree[rt*2+1].sum;
}

void query(int left, int right, int rt, int L, int R)
{
	if(L <= left && R >= right){
		ans += tree[rt].sum;
		return ;
	}
	int mid = tree[rt].mid();
	if(R <= mid)
		query(left, mid, rt*2, L, R);
	else if(L > mid)
		query(mid+1, right, rt*2+1, L, R);
	else
	{
		query(left, mid, rt*2, L, R);
		query(mid+1, right, rt*2+1, L, R);
	}
}

void update(int left, int right, int rt, int pos, int add)
{
	if(left == right)
	{
		tree[rt].sum += add;
		return ;
	}
	int mid = tree[rt].mid();
	if(pos <= mid)
		update(left, mid, rt*2, pos, add);
	else 
		update(mid+1, right, rt*2+1, pos, add);
	tree[rt].sum = tree[rt*2].sum + tree[rt*2+1].sum;
}

int main()
{
	int T, N, temp;
	int a, b, Case = 0;
	string str;
	scanf("%d",&T);
	while(T --)
	{
		cin >> N;
		buildTree(1, N, 1);
		Case ++;
		printf("Case %d:\n",Case);
		while( cin >> str )
		{
			if(str == "End") break;
			scanf("%d%d", &a, &b);
			if(str == "Add"){
				update(1, N, 1, a, b);
			}
			else if(str == "Sub"){
				update(1, N, 1, a, -b);
			}
			else {
				ans = 0;
				query(1, N, 1, a, b);
				printf("%d\n",ans); 
			}
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值