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

来源:互联网 发布:mysql获取第一条记录 编辑:程序博客网 时间:2024/06/05 00:37

问题概述:先输入一个数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;}


原创粉丝点击