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;
}