URAL 1470 二维数组数组

1470. UFOs

Time limit: 5.0 second
Memory limit: 64 MB
Vasya is a ufologist and his duties include observing Unidentified Flying Objects (UFOs) in the part of space bounded by a cubeN × N × N. The cube is divided into cubic sectors 1 × 1 × 1. During the observation, the following events may happen:
  • several new UFOs emerge in a certain sector;
  • several UFOs disappear in a certain sector;
  • Vasya's boss may ask him how many UFOs there are in a part of space consisting of several sectors.
At the moment when Vasya starts his observations there are no UFOs in the whole space.

Input

The first line contains an integer N (1 ≤ N ≤ 128). The coordinates of sectors are integers from 0 to N–1.
Then there are entries describing events, one entry per line. Each entry starts with a number M.
  • If M is 1, then this number is followed by four integersx (0 ≤ x < N), y (0 ≤ y < N), z (0 ≤ z < N), K (–20000 ≤ K ≤ 20000), which are coordinates of a sector and the change in the number of UFOs in this sector. The number of UFOs in a sector cannot become negative.
  • If M is 2, then this number is followed by six integersx1, y1, z1, x2, y2, z2 (0 ≤ x1x2 < N, 0 ≤ y1y2 < N, 0 ≤ z1z2 < N), which mean that Vasya must compute the total number of UFOs in sectors (x, y, z) belonging to the volume: x1xx2, y1yy2, z1zz2.
  • If M is 3, it means that Vasya is tired and goes to sleep. This entry is always the last one.
The number of entries does not exceed 100002.

Output

For each query, output in a separate line the required number of UFOs.

Sample

inputoutput
2
2 1 1 1 1 1 1
1 0 0 0 1
1 0 1 0 3
2 0 0 0 0 0 0
2 0 0 0 0 1 0
1 0 1 0 -2
2 0 0 0 1 1 1
3
0
1
4
2

代码+注释:

#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn 130 
using namespace std ;
int xt[maxn][maxn][maxn] ;
int add , z , n ;
int low( int x )
{
    return x &(-x) ;
}
// 二维树状数组,第三维枚举
void up( int x , int y )
{
    int i , j ;
    for( i = x ; i <= maxn ;i+= low(i))
        for( j = y ; j <= maxn ; j+=low(j))
        {
            xt[z][i][j] += add ;
            if( xt[z][i][j] < 0 ) xt[z][i][j] = 0 ;
        }
}
int sum( int x , int y )
{
    int i ,ans = 0 ;
    for( i = x ;i > 0 ;i -= low(i) ) 
        for( int j = y ; j > 0 ;j -= low(j) ) 
    {
        ans += xt[z][i][j] ;
    }
    return ans ;
}
int main()
{
    int x , y , a ;
    int x1 , y1 , z1 , z2 ;
    int x2 , y2 , ans ;
    while( cin >> n )
    {
        memset( xt , 0 , sizeof(xt)) ;
         while( scanf( "%d" , &a ) && a != 3 )
        {
             ans = 0 ; 
            if( a == 1 )
            {
                scanf( "%d%d%d%d" , &x , &y , &z , &add ) ;
                x+=2 ; y+=2 ; z+=2 ;
                up( x , y ) ;
            }
            else if( a == 2)
            {
                scanf( "%d%d%d" , &x1 , &y1 , &z1 ) ;
                scanf( "%d%d%d" , &x2 , &y2 , &z2 ) ;// 树状数组必须大于0,而且是整数
                x1+=2;x2+=2;y1+=2;y2+=2;z1+=2;z2+=2;
                for( z = z1 ; z <= z2 ;z++ )
                { //求矩阵(x1,y1)(x2,y2) (对角)的和 公式
                    // sum(x2,y2) - sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1)
                 ans+=( sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1) );
                }
                printf("%d\n",ans);
            }
        }
    }
}
原文地址:https://www.cnblogs.com/20120125llcai/p/3119410.html