UFOs(树状数组)

Description

Vasya is a ufologist and his duties include observing Unidentified Flying Objects (UFOs) in the part of space bounded by a cube N × 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 integers x (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 integers x1y1z1x2y2z2 (0 ≤ x1 ≤ x2 < N, 0 ≤ y1 ≤ y2 < N, 0 ≤ z1 ≤ z2 < N), which mean that Vasya must compute the total number of UFOs in sectors (xyz) belonging to the volume: x1 ≤ x ≤ x2y1 ≤ y ≤ y2z1 ≤ z≤ z2.
  • 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 Input

input output
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

解题思路

这题是三维空间上的,看到userluoxuan用三维树状数组做的,但是三维最后求和的式子太麻烦了,还是二维间接求简单些^_^#

就是将不同的z不同的层单独看,更新时更新z相等这一层,最后求和时求出范围内的每一层再相加。



AC代码

#include<stdio.h>
#include<string.h>
#define maxn 130
int xt[maxn][maxn][maxn] ;
int add, z, n ;
int lowbit( int x )
{
    return x&(-x) ;
}

void update(int x, int y )
{
    int i, j ;
    for(i=x; i<=maxn; i+=lowbit(i))
        for(j=y; j<=maxn; j+=lowbit(j))
        {
            xt[z][i][j] += add ;
            if( xt[z][i][j] < 0 )  xt[z][i][j] = 0 ;            //注意更新,求和时带上第三维
        }
}
int get_sum( int x , int y )
{
    int i, ans=0 ;
    for( i=x; i>0; i-=lowbit(i) )
        for(int j=y; j>0; j-=lowbit(j) )
        {
            ans += xt[z][i][j] ;
        }
    return ans ;
}
int main()
{
    int x, y, a;
    int x1, y1, z1, x2, y2, z2;
    int ans;
    scanf("%d", &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 );
            update(x+1, y+1);
        }
        else if( a==2)
        {
            scanf("%d%d%d", &x1, &y1, &z1 );
            scanf("%d%d%d", &x2, &y2, &z2 );
            for(z=z1; z<=z2; z++)
                ans += get_sum(x2+1,y2+1) - get_sum(x1,y2+1) - get_sum(x2+1,y1) + get_sum(x1,y1);

            printf("%d\n",ans);
        }
    }
    return 0;

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值