HDU 3584 树状数组

点击打开链接

题意:三维的空间中有两个操作,初始时每个空间元素均为0,然后更新操作是0变1,1变0,是一个空间内的所有元素都更新,然后查询是问这个点的元素是0还是1

思路:因为不好去更新到每一个点,那么我们可以统计空间的翻转的次数,然后用三维的树状数组即可,但是更新时不能只更新那个点,因为如果这样能的话,能够包括这个区间的大区间因为还没有更新过而和变成了1,那不是我们要的,所以我们将包围这个区间的一圈在更新一次,那么值就加了2,而不会影响结果

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=110;
int sum[maxn][maxn][maxn],n;
int lowbit(int x){return x&(-x);}
void update(int x,int y,int z,int val){
    for(int i=x;i<=n;i+=lowbit(i)){
        for(int j=y;j<=n;j+=lowbit(j)){
            for(int l=z;l<=n;l+=lowbit(l)){
                sum[i][j][l]+=val;
            }
        }
    }
}
int msum(int x,int y,int z){
    int res=0;
    for(int i=x;i>0;i-=lowbit(i)){
        for(int j=y;j>0;j-=lowbit(j)){
            for(int l=z;l>0;l-=lowbit(l)){
                res+=sum[i][j][l];
            }
        }
    }
    return res;
}
int main(){
    int m,x1,y1,z1,x2,y2,z2,type;
    while(scanf("%d%d",&n,&m)!=-1){
        memset(sum,0,sizeof(sum));
        while(m--){
            scanf("%d",&type);
            if(type==1){
                scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
                update(x1,y1,z1,1);update(x1,y1,z2+1,1);
                update(x1,y2+1,z1,1);update(x1,y2+1,z2+1,1);
                update(x2+1,y1,z1,1);update(x2+1,y1,z2+1,1);
                update(x2+1,y2+1,z1,1);update(x2+1,y2+1,z2+1,1);
            }else{
                scanf("%d%d%d",&x1,&y1,&z1);
                printf("%d\n",msum(x1,y1,z1)&1);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(数据结构,线段树,ACM,HDU)