该题可以用树状数组也可以用线段数;
树状数组: #include#include #include int c[50024],sum[50024],N; int lowbit(int x){ return x&(-x); } int SUM(int n){ int sum=0; while(n){ sum=sum+c[n]; n-=lowbit(n); } return sum; } void add(int n,int num){ while(n<=N){ c[n]+=num; n+=lowbit(n); } } int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) { char a[10]; int x,y,m; sum[0]=0;c[0]=0; scanf("%d",&N); for(int j=1;j<=N;j++){ scanf("%d",&x); sum[j]=sum[j-1]+x; c[j]=sum[j]-sum[j-lowbit(j)]; } printf("Case %d:\n",i); while(scanf("%s",a),strcmp(a,"End")){ scanf("%d%d",&x,&y); if(a[0]=='Q'){ int ans=SUM(y)-SUM(x-1); printf("%d\n",ans); } else { if(a[0]=='S')y=-y; add(x,y); } } // puts(""); } return 0; }
线段数: #include#include #include #include using namespace std; class Node { public: int l,r,mid; int count; }; Node tree[200024]; int num[50024]; class Tree { public: void Maketree( int l,int r,int cnt ); void Add( int l,int r, int cnt); int Qestion( int l,int r,int cnt ); }; void Tree::Maketree( int l,int r,int cnt ) { if( l == r ) { tree[cnt].l = tree[cnt].r = l; tree[cnt].mid = l; tree[cnt].count = num[l]; return ; } else { tree[cnt].l = l; tree[cnt].r = r; tree[cnt].mid = ( l + r )>>1; Maketree( l , tree[cnt].mid , cnt*2 ); Maketree( tree[cnt].mid +1 , r, cnt*2 +1 ); tree[cnt].count = tree[cnt*2].count + tree[cnt*2+1].count; } } void Tree::Add( int n,int m, int cnt ) { if( tree[cnt].l == n&&tree[cnt].r==n ) { tree[cnt].count += m; return; } else { if( n > tree[cnt].mid ) Add( n , m , cnt*2+1 ); else Add( n , m ,cnt*2 ); tree[cnt].count += m; } } int Tree::Qestion( int l,int r,int cnt ) { if( l==tree[cnt].l&&r==tree[cnt].r ) return tree[cnt].count; else { if( l > tree[cnt].mid ) return Qestion( l, r, cnt*2+1 ); else { if( r <= tree[cnt].mid ) return Qestion( l , r ,cnt*2 ); else { return Qestion( l , tree[cnt].mid, cnt*2 )+Qestion( tree[cnt].mid+1,r, cnt*2+1 ); } } } } int main( ) { int Case,n,l,r; char c[10]; while( scanf( "%d",&Case )==1 ) { Tree e; for( int i=1; i<=Case ; i++ ) { printf( "Case %d:\n",i ); scanf( "%d",&n ); for( int j=1; j<= n; j++ ) scanf( "%d",&num[j] ); e.Maketree( 1,n,1 ); while( scanf( "%s",c ),c[0]!='E' ) { scanf( "%d%d",&l,&r ); if( c[0]=='A' ) e.Add( l,r,1 ); else if( c[0]=='S' ) e.Add( l , -1*r,1 ); else printf( "%d\n",e.Qestion( l,r,1 ) ); } } } return 0; }