树状数组--快捷的线段树

问题概述:先输入一个数n,接下来输入n个数,然后输入一个指令,其中(Add i j)i和j为正整数,表示第i个营地增加j个人,(Sub i j)i和j为正整数,表示第i个营地减少j个人,(Query i j)i和j为正整数,i<=j,表示询问第i到第j个营地的总人数,(End)表示结束,这条命令在每组数据最后出现,对于每个Query询问,输出该区间中的总人数(T组实例)

输入样例:                                                对应输出:

1                                                                Case 1:

10                                                               6

1 2 3 4 5 6 7 8 9 10                                  3

Query 1 3                                                  59

Add 3 6

Query 2 7

Sub 10 2

Add 6 3

Query 3 10

End 


大神:http://blog.csdn.net/int64ago/article/details/7429868

解析在代码中

#include<stdio.h>
#include<string.h>
int n;
int c[50005];
void Update(int x, int k);
int Print(int k);
int lowbit(int k)
{
	return k&-k;	/*把k的二进制的高位1全部清空,只留下最低位的1*/
}
int main(void)
{
	int T, cas, i, a, b;
	char str[12];
	scanf("%d", &T);
	cas = 1;
	while(T--)
	{
		memset(c, 0, sizeof(c));	/*将数组的所有元素全部重置为0*/
		scanf("%d", &n);
		for(i=1;i<=n;i++)
		{
			scanf("%d", &a);
			Update(a, i);		/*每输入一个数,更新一次树状数组*/
		}
		printf("Case %d:\n", cas++);
		while(scanf("%s", str), strcmp(str, "End")!=0)
		{
			scanf("%d%d", &a, &b);
			if(str[0]=='A')
				Update(b, a);
			if(str[0]=='S')
				Update(-b, a);
			if(str[0]=='Q')
				printf("%d\n", Print(b)-Print(a-1));
		}
	}
	return 0;
}

void Update(int x, int k)	/*树状数组的更新*/
{
	while(k<=n)
	{
		c[k] += x;
		k += lowbit(k);
	}
}

int Print(int k)		/*查询1-k的区间和*/
{
	int ans;
	ans = 0;
	while(k>0)
	{
		ans += c[k];
		k -= lowbit(k);
	}
	return ans;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值