http://acm.hdu.edu.cn/showproblem.php?pid=1166
都认为这是线段树的基础题, 我就通过这个题来学习一下线段树,对于线段树的介绍网上有很多,线段树就是一个完全二叉树。对于更新和修改设计到一棵树的很多个节点。以后慢慢做深入研究。
#include <stdio.h> #include <string.h> #define MAX 50005 char str[6]; typedef struct _node { int left; int right; int count; }node; node no[MAX*3]; int num[MAX], value, a, res; int n; //建树 void insert(int l, int r, int i) { no[i].left = l, no[i].right = r; if(l == r){ no[i].count = num[l]; return ; } int mid = (l+r)/2; insert(l, mid, i*2); insert(mid+1, r, i*2+1); no[i].count = no[i*2].count + no[i*2+1].count; } //按要求修改树 void modify(int l, int r, int i) { if(no[i].left == no[i].right){ no[i].count+=value; return; } int mid = (no[i].left+no[i].right)/2; if(a <= mid){ modify(l, r, i*2); } else { modify(l, r, i*2+1); } no[i].count = no[i*2].count+no[i*2+1].count; } //查询 void query(int start, int end, int i) { if(start==no[i].left&&end==no[i].right){ res += no[i].count; return ; } int mid = (no[i].left+no[i].right)/2; if(end <= mid){ query(start, end, i*2); } else if(start > mid){ query(start, end, i*2+1); } else{ query(start, mid, i*2); query(mid+1, end, i*2+1); } } int main() { // freopen("input.txt","r", stdin); int t,i,j; scanf("%d", &t); for(i = 1; i <= t; i ++){ printf("Case %d:\n", i); scanf("%d", &n); // scanf("%*c"); for(j = 1; j <= n; j ++){ scanf("%d", &num[j]); } insert(1, n, 1); while(scanf("%s",str)&&strcmp(str, "End")!=0){ scanf("%d%d", &a, &value); // scanf("%*c"); if(strcmp(str, "Add")==0){ modify(1, n, 1); } else if(strcmp(str, "Sub")==0){ value=-value; modify(1, n, 1); } else{ res = 0; query(a, value, 1); printf("%d\n", res); } } } return 0; }