/**
* poj1656 二维树状数组
* 二维线段树的做法太繁琐了,暂时先不看了,二维树状数组的做法相对简单些,但题目中这样的实现,确实减轻了查询的复杂度,但是插入的复杂度却确实提升了比较多
* 思路大概就是在一维的树状数组的插入和查询操作循环内部嵌套一个另一维的操作就可以了
* 听说这个题暴力也能过,所以看样子并不会对复杂度控制太高吧
*/
#include <cstdio>
#include <cstring>
bool board[101][101];
int tree[101][101];
int lowbit(int x){
return x&(-x);
}
void update(int x,int y,bool color){
while(x<=100){
int yy = y;
while(yy<=100){
tree[x][yy]+=(color)?1:-1;
yy+=lowbit(yy);
}
x+=lowbit(x);
}
}
int getsum(int x,int y){
int sum=0;
while(x>0){
int yy=y;
while(yy>0){
sum+=tree[x][yy];
yy-=lowbit(yy);
}
x-=lowbit(x);
}
return sum;
}
int main(){
int t,x,y,l;
char command[6];
scanf("%d",&t);
memset(board,0,sizeof(board));
memset(tree,0,sizeof(tree));
while(t--){
scanf("%s",command);
scanf("%d%d%d",&x,&y,&l);
switch(command[0]){
case 'B'://BLACK
for(int i=x;i<x+l;++i){
for(int j=y;j<y+l;++j){
if(!board[i][j]){
update(i,j,true);
board[i][j] = true;
}
}
}
break;
case 'W'://WHITE
for(int i=x;i<x+l;++i){
for(int j=y;j<y+l;++j){
if(board[i][j]){
update(i,j,false);
board[i][j] = false;
}
}
}
break;
case 'T'://TEST
printf("%d\n",getsum(x+l-1,y+l-1) + getsum(x-1,y-1) - getsum(x-1,y+l-1) - getsum(x+l-1,y-1));
break;
default:
printf("error occurs\n");
break;
}
}
return 0;
}
poj1656 二维树状数组
最新推荐文章于 2017-10-11 13:23:34 发布