线段树 (本题无需建树,少了很多)
#include<cstdio> #include<cstring> int sum[5000005],rt,data,lb,rb,n,m; void add(int p,int l,int r,int now)//data新加的数 第p个位置 第now个子树 { sum[now]+=data; if(l==r) return; int mid=(l+r)/2; if(p<=mid) add(p,l,mid,2*now); else add(p,mid+1,r,2*now+1); } int query(int l,int r,int now) { int mid=(l+r)/2; if(lb<=l&&rb>=r) return(sum[now]); if(rb<=mid) return(query(l,mid,2*now)); else if(lb>mid) return(query(mid+1,r,2*now+1)); else return(query(l,mid,2*now)+query(mid+1,r,2*now+1)); } int main() { int t,tt,i,j; char s[100]; scanf("%d",&t); for(tt=1;tt<=t;tt++){ scanf("%d",&n); printf("Case %d: ",tt); memset(sum,0,sizeof(sum)); for(i=1;i<=n;i++){ scanf("%d",&data); add(i,1,n,1); } while(1){ scanf("%s",&s); if(s[0]=='E') break; else scanf("%d%d",&i,&j); switch(s[0]){ case 'A':data=j;add(i,1,n,1);break; case 'S':data=-j;add(i,1,n,1);break; case 'Q':lb=i;rb=j;printf("%d ",query(1,n,1));break; } } } return 0; }
简单的树状数组
先给个经典图片
#include<iostream> #include<cstdio> #include<cstring> int n,a[50005]; int lowbit(int a) { return(a&(-a)); } void add(int p,int q) { for(int i=q;i<=n;i+=lowbit(i)) a[i]+=p; } int sum(int q) { int ans=0; for(int i=q;i>0;i-=lowbit(i)) ans+=a[i]; return(ans); } int main() { int t,tt,i,j,k; char s[100]; scanf("%d",&t); for(tt=1;tt<=t;tt++){ scanf("%d",&n); printf("Case %d: ",tt); memset(a,0,sizeof(a)); for(i=1;i<=n;i++){ scanf("%d",&k); add(k,i); } while(1){ scanf("%s",&s); if(s[0]=='E') break; else scanf("%d%d",&i,&j); switch(s[0]){ case 'A':add(j,i);break; case 'S':add(-j,i);break; case 'Q':printf("%d ",sum(j)-sum(i-1));break; } } } return 0; }