题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3584
这个题目树状数组比较明显
由于只是两种变化,所以只要统计变化的次数就可以了
每次变化的是一个区间,更新的时候就按照点一样的更新方法
求和时求某个点的,其实就是求变化次数
任何一段在往下加的时候总能加到你更新的那个位置,如果加不到你也一定会加到你的某个
上司,没影响的也会加,不过更新的时候考虑到这个问题,把重复位置再次更新了一次,因为
奇偶变化,都+就行了!
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 105;
int tree[maxn][maxn][maxn];
int n,m;
int lowbit(int x){
return (-x)&x;
}
int sum(int i,int j,int k){
int ans=0,now,then;
while(i>0){
now=j;
while(now>0){
then=k;
while(then>0){
ans+=tree[i][now][then];
then-=lowbit(then);
}
now-=lowbit(now);
}
i-=lowbit(i);
}
return ans;
}
int update(int i,int j,int k){
int now,then;
while(i<=n){
now=j;
while(now<=n){
then=k;
while(then<=n){
tree[i][now][then]++;
then+=lowbit(then);
}
now+=lowbit(now);
}
i+=lowbit(i);
}
return 0;
}
int main(){
int i,j,k;
int no,x1,y1,z1,x2,y2,z2;
while(scanf("%d%d",&n,&m)!=EOF){
memset(tree,0,sizeof(tree));
for(i=0;i<m;i++){
scanf("%d",&no);
if(1==no){
scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
update(x1,y1,z1);
update(x1,y1,z2+1);
update(x1,y2+1,z1);
update(x2+1,y1,z2+1);
update(x2+1,y2+1,z1);
update(x1,y2+1,z2+1);
update(x2+1,y1,z1);
update(x2+1,y2+1,z2+1);
}else{
scanf("%d%d%d",&x1,&y1,&z1);
printf("%d\n",sum(x1,y1,z1)%2);
}
}
}
return 0;
}
本文解析了HDU 3584题目的解决方案,使用树状数组来统计区间内的变化次数。通过更新特定区间的点值,并利用树状数组的特性进行查询,最终解决二维区间翻转问题。
693

被折叠的 条评论
为什么被折叠?



