/*1166 敌兵布阵*/ #include<stdio.h> #include<string.h> #define N 50005 struct node{ int l; int r; int sum; }; node tree[3*N];//数大了,要开全局变量,不过有点矛盾,因为看了老师给的一本书说尽量不要用全局变量 int num[N]; //三个子函数都用到几乎一样的思想 void buid_tree(node *pt,int *pn,int k,int left,int right) { (pt+k)->l = left; (pt+k)->r = right; if(right - left == 1){ (pt+k)->sum = *(pn+left); return ; } buid_tree(pt,pn,2*k,left,(left+right)/2); buid_tree(pt,pn,2*k+1,(left+right)/2,right); (pt+k)->sum = (pt+2*k)->sum+(pt+2*k+1)->sum; } void insert_tree(node *pt,int k,int x,int y,int v) { int mid = ((pt+k)->l+(pt+k)->r)/2; if(x <= (pt+k)->l && y >= (pt+k)->r){ (pt+k)->sum += v; return ; } if(x < mid) insert_tree(pt,2*k,x,y,v); if(y > mid) insert_tree(pt,2*k+1,x,y,v); (pt+k)->sum = (pt+2*k)->sum+(pt+2*k+1)->sum; } int search_tree(node *pt,int k,int x,int y) { int ls = 0,rs = 0; int mid; if(x <= (pt+k)->l && y >= (pt+k)->r) return (pt+k)->sum; mid = ((pt+k)->l+(pt+k)->r)/2; if(x < mid) ls = search_tree(pt,2*k,x,y); if(y > mid) rs = search_tree(pt,2*k+1,x,y); return ls+rs; } int main() { int i; int a,b; int sum; int tcase,walk = 0; int n; char str[6]; scanf("%d",&tcase); while(tcase--){ scanf("%d",&n); for(i = 1;i <= n;i++){ scanf("%d",&num[i]); } buid_tree(tree,num,1,1,n+1);//每个结点是半开半闭区间,须+1 printf("Case %d:/n",++walk); while(1){ scanf("%s",str); if(!strcmp(str,"Add")){ scanf("%d %d",&a,&b); insert_tree(tree,1,a,a+1,b); } if(!strcmp(str,"Sub")){ scanf("%d %d",&a,&b); b = -b; insert_tree(tree,1,a,a+1,b); } if(!strcmp(str,"Query")){ scanf("%d %d",&a,&b); sum = search_tree(tree,1,a,b+1); printf("%d/n",sum); } if(!strcmp(str,"End")) break; } } return 0; } //哎~~~~调了一个晚上,依然有些不明白的地方,越调就越在想自己实在太菜了,其实这应该是 //什分简单的水题吧,然而自己却要花如此多的时间才完成,我是不是真的那么笨 //这几乎是看ppt做出来的,之前看算法导论时好像和这不一样,它的不是树状数组,也不是这样, //好似是红黑树,没看过前面真的看得我蛋疼~~~~好!!!睡明天再写个树状数组的,coding,coding //笨也要coding,因为我喜欢^-^!!