hdu Cube

1 篇文章 0 订阅
1 篇文章 0 订阅

Cube

Problem Description
Given an N*N*N cube A, whose elements are either 0 or 1. A[i, j, k] means the number in the i-th row , j-th column and k-th layer. Initially we have A[i, j, k] = 0 (1 <= i, j, k <= N).
We define two operations, 1: “Not” operation that we change the A[i, j, k]=!A[i, j, k]. that means we change A[i, j, k] from 0->1,or 1->0. (x1<=i<=x2,y1<=j<=y2,z1<=k<=z2).
0: “Query” operation we want to get the value of A[i, j, k].
Input
Multi-cases.
First line contains N and M, M lines follow indicating the operation below.
Each operation contains an X, the type of operation. 1: “Not” operation and 0: “Query” operation.
If X is 1, following x1, y1, z1, x2, y2, z2.
If X is 0, following x, y, z.
Output
For each query output A[x, y, z] in one line. (1<=n<=100 sum of m <=10000)
Sample Input
2 5
1 1 1 1 1 1 1
0 1 1 1
1 1 1 1 2 2 2
0 1 1 1
0 2 2 2
Sample Output
1
0
1
Author
alpc32
Source
2010 ACM-ICPC Multi-University Training Contest(15)——Host by NUDT

考虑2维的情况

12345
678910
1112131415
1617181920

如果在1格至13格的地方取反,首先在1格+1,但16格不在取反范围内,那么在16格处+1,使16格的左上角前缀和除以二的余数为0。此时17,18格左上角前缀和除以二的余数恰好也为为0,因此不做修改。同理,4格处也要+1,然后5,9,10,14,15处不做修改。因为19格的前缀和是奇数,所以19格也+1,20格不做修改。
用树状数组维护+1的差分操作,至此二维情况解决。
推广到三维
图画不出来,所以自行脑补。
总之保证修改的范围内三维前缀和为奇数,范围外前缀和为偶数。

#include<cstdio>
#include<cstring>
#define N 105
#define LL long long
#define lowbit(x) (x & (-x))
using namespace std;

inline int getint() {
    char ch;
    int p=0;
    for(ch=getchar();!(ch>='0' && ch<='9');ch=getchar());
    for(;ch>='0' && ch<='9';ch=getchar()) {
        p=p*10+ch-48;
    }
    return p;
}

int n,m;
int c[N][N][N],i1,j1,k1,i2,j2,k2;

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

int query(int x,int y,int z) {
    int acht=0;
    for(int i=x;i>0;i=i-lowbit(i)) {
        for(int j=y;j>0;j=j-lowbit(j)) {
            for(int k=z;k>0;k=k-lowbit(k)) {
                acht+=c[i][j][k];
            }
        }
    }
    return acht;
}

int main()
{
    while(scanf("%d%d",&n,&m)==2) {
        memset(c,0,sizeof c);
        while(m--) {
            int D=getint();
            if(D==1) {
                i1=getint();
                j1=getint();
                k1=getint();
                i2=getint();
                j2=getint();
                k2=getint();
                updata(i1,j1,k1,1);
                updata(i2+1,j1,k1,1);
                updata(i1,j2+1,k1,1);
                updata(i1,j1,k2+1,1);
                updata(i1,j2+1,k2+1,1);
                updata(i2+1,j1,k2+1,1);
                updata(i2+1,j2+1,k1,1);
                updata(i2+1,j2+1,k2+1,1);
            } else if(D==0) {
                i1=getint();
                j1=getint();
                k1=getint();
                printf("%d\n",query(i1,j1,k1)&1);
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值