赤裸裸的线段树,借个模板,改写一下即可。
代码:
#include<iostream> #include<cstdio> #include<stdio.h> #include<cstring> using namespace std; struct line{ int left,right,n; int mid(){return (left+right)/2;} }a[50010<<2]; unsigned short num[50010]; void build(int l,int r,int step) { a[step].left=l; a[step].right=r; if(l==r) { a[step].n=num[l]; return; } int mid=a[step].mid(); build(l,mid,step*2); build(mid+1,r,step*2+1); a[step].n=a[step*2].n+a[step*2+1].n; } int query(int l,int r,int step) { if(a[step].left==l&&a[step].right==r) return a[step].n; int mid=a[step].mid(); if(mid>=r) return query(l,r,step*2); else if(mid<l) return query(l,r,step*2+1); else return query(l,mid,step*2)+query(mid+1,r,step*2+1); } void Add(int l,int r,int step,int x,int y) { if(a[step].left==a[step].right&&a[step].right==x) { a[step].n+=y; return ; } int mid=a[step].mid(); if(x>mid) Add(mid,r,step*2+1,x,y); else Add(l,mid,step*2,x,y); a[step].n=a[step*2].n+a[step*2+1].n; } void Sub(int l,int r,int step,int x,int y) { if(a[step].left==a[step].right&&a[step].right==x) { a[step].n-=y; return ; } int mid=a[step].mid(); if(x>mid) Sub(mid,r,step*2+1,x,y); else Sub(l,mid,step*2,x,y); a[step].n=a[step*2].n+a[step*2+1].n; } int main() { int t,n; scanf("%d",&t); for(int tcase=1;tcase<=t;tcase++) { printf("Case %d: ",tcase); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&num[i]); build(1,n,1); char in[6]; int x,y; while(scanf("%s",&in)&&strcmp(in,"End")!=0)//字符数组匹配,弄得我好惨 { scanf("%d%d",&x,&y); if(strcmp(in,"Query")==0) printf("%d ",query(x,y,1)); else if(strcmp(in,"Sub")==0) Sub(1,n,1,x,y); else if(strcmp(in,"Add")==0) Add(1,n,1,x,y); } } return 0; }