UFOs ——三维树状数组

UFOs
Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

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


题意和POJ1195 Mobile phones差不多,只不过是把情况推到三维。做Mobile phones时得到了二维的公式,求三维的只不过是V=S*(z-z1)罢了,化简一下就出结果了。附POJ1195解题报告点击打开链接

AC代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#include<set>
#define ll long long
using namespace std;
const int MAX=1<<28;
int n,c[130][130][130];
inline int lowbit(int x)
{
    return x&-x;
}

void updata(int x,int y,int z,int dt)
{
    int i,j,k;
    for(i=x;i<=n+1;i+=lowbit(i))
        for(j=y;j<=n+1;j+=lowbit(j))
          for(k=z;k<=n+1;k+=lowbit(k))
          c[i][j][k]+=dt;
}

ll sum(int x,int y,int z)
{
    int i,j,k;
    ll ans=0;
    for(i=x;i>0;i-=lowbit(i))
        for(j=y;j>0;j-=lowbit(j))
          for(k=z;k>0;k-=lowbit(k))
            ans+=c[i][j][k];
    return ans;
}
int main()
{
    memset(c,0,sizeof(c));
    scanf("%d",&n);
    int type,x1,y1,z1,x,y,z,val;
    while(scanf("%d",&type))
    {
        if(type==3) break;
        if(type==1)
        {
            scanf("%d%d%d%d",&x1,&y1,&z1,&val);
            updata(x1+1,y1+1,z1+1,val);
        }
        else if(type==2)
        {
            scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x,&y,&z);
            x++; y++; z++;
            ll ans;
            ans=sum(x,y,z)-sum(x,y,z1)-sum(x,y1,z)-sum(x1,y,z);
            ans+=sum(x1,y1,z)+sum(x1,y,z1)+sum(x,y1,z1);
            ans-=sum(x1,y1,z1);
            printf("%d\n",ans);
        }
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值