可以用二维线段树与二维树状数组做:
二位数状数组:
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #include<string> #define LL long long using namespace std; LL c[1025][1025]; int lowbit( int x ) { return ( x )&(-x); } void modify( int x, int y , int n ,int A ) { for( int i = x ; i <= n ; i += lowbit(i) ) for( int j = y ; j <= n ; j += lowbit(j) ) c[i][j] += A; } LL Sum( int x1, int y1 , int n ) { LL sum = 0; for( int i = x1 ; i >0 ; i -= lowbit(i) ) for( int j = y1 ; j >0 ; j -= lowbit(j) ) sum += c[i][j]; return sum; } int main( ) { int n,x1,y1,x2,y2,opt,A; while( scanf( "%d",&opt )==1 ) { scanf( "%d",&n ); memset( c , 0 , sizeof( c ) ); while( scanf( "%d",&opt ),opt!=3 ) { switch( opt ) { case 1:scanf( "%d %d %d",&x1,&y1,&A ); modify( x1+1 , y1+1 ,n, A ); break; case 2:scanf( "%d %d %d %d",&x1,&y1,&x2,&y2 ); LL sum=Sum(x1,y1,n)+Sum(x2+1,y2+1,n)-Sum(x2+1,y1,n)-Sum(x1,y2+1,n); printf( "%I64d\n",sum ); } } } //system( "pause" ); return 0; }
二维线段树:
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #include<string> #define LL long long using namespace std; class Node { public: int l,r,sum; }; class Tree { public: int l,r; Node n[4100]; }T[4100]; LL sum ; void build_y( Node *p , int l, int r , int cnt ) { p[cnt].l = l ; p[cnt].r = r; p[cnt].sum = 0; if( l == r ) return; int mid = ( l + r ) >>1; build_y( p ,l , mid , cnt*2 ); build_y( p , mid+1 , r , cnt *2 + 1 ); } void build( int l, int r , int cnt , int N ) { T[cnt].l = l; T[cnt].r = r; build_y( T[cnt].n , 0 , N , 1 ); if( l == r ) return ; int mid = ( l + r ) >> 1; build( l , mid , cnt*2 , N ); build( mid + 1 , r , cnt* 2 + 1, N ); } void modify_y( Node *p , int l, int r, int A, int cnt ) { p[cnt].sum += A; if( p[cnt].l == p[cnt].r ) return; int mid = ( p[cnt].l + p[cnt].r )>>1; if( mid >= r ) modify_y( p , l , r, A ,cnt*2 ); else modify_y( p , l ,r , A ,cnt*2 + 1 ); } void modify( int l, int r , int y1 , int y2 ,int A, int cnt ) { modify_y( T[cnt].n , y1 ,y2 ,A ,1 ); if( T[cnt].l == T[cnt].r ) return; int mid = ( T[cnt].l + T[cnt].r )>>1; if( mid >= r ) modify( l , r , y1 ,y2 ,A , cnt*2 ); else modify( l , r , y1 ,y2 ,A ,cnt*2 +1 ); } void Query_y( Node *p , int l, int r, int cnt ) { if( l <= p[cnt].l && r >= p[cnt].r ) { sum += p[cnt].sum; return; } int mid = ( p[cnt].l + p[cnt].r )>>1; if( mid >= r )Query_y( p , l , r , cnt*2 ); else if( mid < l ) Query_y( p , l , r ,cnt*2 +1 ); else { Query_y( p , l , mid , cnt*2 ); Query_y( p , mid +1 , r , cnt*2 +1 ); } } void Query( int l, int r, int y1 , int y2, int cnt ) { if( l <= T[cnt].l && T[cnt].r <= r ) { Query_y( T[cnt].n , y1 , y2 ,1 ); return; } int mid = ( T[cnt].l + T[cnt].r )>>1; if( mid >= r ) Query( l , r , y1 , y2 ,cnt*2 ); else if( mid < l ) Query( l , r, y1 ,y2 , cnt*2+1 ); else { Query( l , mid , y1,y2 ,cnt*2 ); Query( mid + 1 , r , y1, y2 , cnt*2 + 1 ); } } int main( ) { int n,x1,y1,x2,y2,opt,A; while( scanf( "%d",&opt )==1 ) { scanf( "%d",&n ); build( 0 , n -1 , 1 , n -1 ); while( scanf( "%d",&opt ),opt!=3 ) { switch( opt ) { case 1:scanf( "%d %d %d",&x1,&y1,&A ); modify( x1 ,x1 , y1 , y1 , A ,1 ); break; case 2:scanf( "%d %d %d %d",&x1,&y1,&x2,&y2 ); sum = 0; Query( x1 , x2 , y1 ,y2 ,1); printf( "%I64d\n",sum ); } } } //system( "pause" ); return 0; }