HDU3584 Cube
Posted autoint
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3584 Cube相关的知识,希望对你有一定的参考价值。
分析
三维树状数组,跟二维的差不多,只不过容斥的不一样。
更新区间((x_1,y_1,z_1)
ightarrow(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
",sum(x,y,z)%2);
}
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
以上是关于HDU3584 Cube的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 3584 Cube (三维树状数组 + 区间改动 + 单点求值)