HDU3584 Cube

分析

三维树状数组,跟二维的差不多,只不过容斥的不一样。
更新区间\((x_1,y_1,z_1)\rightarrow(x_2,y_2,z_2)\)时,需要利用容斥原理。须要更新的节点更新如下:
\[ (x_1,y_1,z_1),\\ (x_2+1,y_1,z_1), (x_1,y_2+1,z_1), (x_1,y_1,z_2+1),\\ (x_1,y_2+1,z_2+1), (x_2+1,y_1,z_2+1), (x_2+1,y_2+1,z_1),\\ (x_2+1,y_2+1,z_2+1) \]
更高维的分类讨论就不容易了,可以找规律,利用容斥原理。其实有一点组合的味道。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=110;
int a[MAXN][MAXN][MAXN],n;

int lowbit(int x)
{
    return x&-x;
}

void add(int x,int y,int z,int v)
{
    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]+=v;
}

int sum(int x,int y,int z)
{
    int res=0;
    for(int i=x;i;i-=lowbit(i))
        for(int j=y;j;j-=lowbit(j))
            for(int k=z;k;k-=lowbit(k))
                res+=a[i][j][k];
    return res;
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int m;
    while(~scanf("%d %d",&n,&m))
    {
        memset(a,0,sizeof(a));
        while(m--)
        {
            int opt;
            read(opt);
            if(opt==1)
            {
                int x1,y1,z1,x2,y2,z2;
                read(x1);read(y1);read(z1);read(x2);read(y2);read(z2);
                add(x1,y1,z1,1);
                add(x2+1,y1,z1,1);
                add(x1,y2+1,z1,1);
                add(x1,y1,z2+1,1);
                add(x1,y2+1,z2+1,1);
                add(x2+1,y1,z2+1,1);
                add(x2+1,y2+1,z1,1);
                add(x2+1,y2+1,z2+1,1);
            }
            else
            {
                int x,y,z;
                read(x);read(y);read(z);
                printf("%d\n",sum(x,y,z)%2);
            }
        }
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/9573237.html