HDU 3584 树状数组

来源:互联网 发布:耐玩的单机游戏 知乎 编辑:程序博客网 时间:2024/05/29 16:47

点击打开链接

题意:三维的空间中有两个操作,初始时每个空间元素均为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;}

0 0