线段树(Segment Tree)与树状数组(Binary Indexed Tree)两种写法
ST为单点更新
以后能用BIT写的还是用BIT吧。。
///ST #include <stdio.h> #include <string.h> const int MAXN = 50005; int save[MAXN]; struct ST { int left,right,mid,val; }node[3*MAXN]; void make(int l,int r,int num) { node[num].left = l ; node[num].right= r ; node[num].mid = (l+r)>>1; if(r==l) return; make(l,node[num].mid,num<<1); make(node[num].mid+1,r,num<<1|1); } void insert(int pos,int val,int num) { node[num].val+=val; //printf("pos:%d\n",pos); //printf("num:%d\t%d\t%d\nval:%d\n",num,node[num].left,node[num].right,node[num].val); if(node[num].left==pos&&node[num].right==pos) return; if(pos<=node[num].mid) insert(pos,val,num<<1); else insert(pos,val,num<<1|1); } int cal(int l,int r,int num) { /*printf("num:%d\t%d\t%d\nval:%d\n",num,node[num].left,node[num].right,node[num].val); printf("LR:%d\t%d\n",l,r); puts("");*/ if(node[num].left>=l&&node[num].right<=r) return node[num].val; if(node[num].left>r||node[num].right<l) return 0; return cal(l,r,num<<1)+cal(l,r,num<<1|1); } int main() { int T,C=1; scanf("%d",&T); while(T--) { printf("Case %d:\n",C++); memset(node,0,sizeof(node)); int n; scanf("%d",&n); make(1,n,1); for(int i=0;i<n;i++) { scanf("%d",&save[i+1]); insert(i+1,save[i+1],1); } /*for(int i=1;i<=n;i++) { printf("*%d\t",node[i].val); }*/ char com[100]; int a,b; while(1) { scanf("%s",com); if(com[0]=='E') break; scanf("%d%d",&a,&b); if(com[0]=='A') insert(a,b,1); else if(com[0]=='S') insert(a,-b,1); else if(com[0]=='Q') printf("%d\n",cal(a,b,1)); } } return 0; }
///BIT #include <stdio.h> #include <string.h> const int MAXN = 50005; int c[MAXN],n; int lowbit(int x) { return x&(-x); } void insert(int pos,int val) { while(pos<=n) { c[pos]+=val; pos+=lowbit(pos); } } int cal(int pos) { int sum=0; while(pos>0) { sum+=c[pos]; pos-=lowbit(pos); } return sum; } int main() { int T,cnt=1; scanf("%d",&T); while(T--) { printf("Case %d:\n",cnt++); memset(c,0,sizeof(c)); scanf("%d",&n); for(int i=0;i<n;i++) { int tmp; scanf("%d",&tmp); insert(i+1,tmp); } char com[20]; int a,b; while(1) { scanf("%s",com); if(com[0]=='E') break; scanf("%d%d",&a,&b); switch (com[0]) { case 'A':insert(a,b);break; case 'S':insert(a,-b);break; case 'Q':printf("%d\n",cal(b)-cal(a-1));break; } } } return 0; }