HDU3584 Cube 三维树状数组

来源:互联网 发布:特朗普移民禁令 知乎 编辑:程序博客网 时间:2024/05/16 16:14

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3584


题目大意:给定一个N* N* N多维数据集A,其元素是0或1。A[I,j,k]代表集合中中的第i行,第j列与第k层的值。首先,我们有A [i,j,k]= 0(1<= i,j,k<= N)。

我们定义了两个操作,1:“Not”,我们改变A [i,j,k]=!A [i,j,k]的操作。这意味着我们改变A[i,j,k]从0 - >1或1 - > 0。(x1<=i<=x2,y1<=j<=y2,z1<=k<=z2)。

0:“查询”的操作,我们希望得到A [i,j,k]的值。


实现代码如下:

/*三维树状数组0 表示查询1 表示更新区间(取反)*/#include <cstdio>#include <cstring>using namespace std;const int M=105;int a[M][M][M];int n,m;int lowbit(int i){    return i&(-i);}void update(int x,int y,int z){    for(int i=x;i<=n;i+=lowbit(i))      for(int j=y;j<=n;j+=lowbit(j))        for(int k=z;k<=n;k+=lowbit(k))          a[i][j][k]++;}int query(int x,int y,int z){    int sum=0;    for(int i=x;i>0;i-=lowbit(i))      for(int j=y;j>0;j-=lowbit(j))        for(int k=z;k>0;k-=lowbit(k))          sum+=a[i][j][k];    return sum;}int main(){    while(scanf("%d%d",&n,&m)!=-1)    {        memset(a,0,sizeof(a));        int op,x,y,z,x1,y1,z1;        while(m--)        {            scanf("%d%d%d%d",&op,&x,&y,&z);            if(op==0)              printf("%d\n",query(x,y,z)&1);            else            {                scanf("%d%d%d",&x1,&y1,&z1);                update(x,y,z);                update(x,y,z1+1);                update(x,y1+1,z);                update(x,y1+1,z1+1);                update(x1+1,y,z);                update(x1+1,y,z1+1);                update(x1+1,y1+1,z);                update(x1+1,y1+1,z1+1);            }        }    }    return 0;}



扩展--多维树状数组实现代码如下:

//由二维树状数组和三维树状数组可以推出多维树状数组的一般形式。//对于一个n维的树状数组,其更新操作如下int Update (int w,int x,int y,int z....){for(int x1=x;x1<=n;x1+=lowbit(x1))for(int x2=y;x2<=n;x2+=lowbit(x2))for(int x3=z;x3<=n;x3+=lowbit(x3))....c[x1][x2][x3][....]+=w;return ;}//其时间复杂度为O(log(n)^k)。//其查询操作如下int Query(int x,int y,int z,....){int ans=0;for(int x1=x;x1>0;x1-=lowbit(x1))for(int x2=y;x2>0;x2-=lowbit(x2))for(int x3=z;x3>0;x3-=lowbit(x3))....ans+=c[x1][x2][x3][....];return ans;}


0 0
原创粉丝点击