題目鏈接:
http://poj.org/problem?id=2155
題目大意:
給一個n*n的矩陣,有k個詢問。詢問分更新和詢問操作。
更新操作是對某個小的矩陣進行變換,裏面的數(0變1,1變0)。
詢問操作是單點詢問,問當前這個數是0 還是1。
範圍:
n<=1000,k<=5000.
思路:
二維樹狀數組。
二維的樹狀數組其實就是在一維樹狀數組的基礎上面加了一維。
c[i][j]就代表了從a[1][1]到從c[i][j]的總和,方式和一維樹狀數組是一樣的。
那麼這道題目就是區間更新,單點查詢。
區間更新時,我們可以通過update(x1,y1),update(x2+1,y2+1),update(x1,y2+1),update(x2+1,y1)。然後查詢的時候就可以看這個點累加了幾次,如果是偶數次就是0,否則就是1。
代碼:
#include<stdio.h>
#include<string.h>
int c[1005][1005],n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y,int z)
{
int i, j;
for( i=x;i<=n;i+=lowbit(i))
for( j=y;j<=n;j+=lowbit(j))
{
c[i][j]+=z;
}
}
int query(int x,int y)
{
int ans=0,i,j;
for(i=x;i>0;i-=lowbit(i))
for(j=y;j>0;j-=lowbit(j))
{
ans+=c[i][j];
}
return ans;
}
int main()
{
char s[3];
int T,X,i,j,k,x1,x2,y1,y2;
scanf("%d",&T);
while(T--)
{
memset(c,0,sizeof(c));
scanf("%d%d",&n,&X);
while(X--)
{
scanf("%s%d%d",s,&x1,&y1);
if(s[0]=='C'){
scanf("%d%d",&x2,&y2);
update(x1,y1,1);
update(x2+1,y2+1,1);
update(x1,y2+1,1);
update(x2+1,y1,1);
}
else {
int xx=query(x1,y1);
if(xx%2)printf("1\n");
else printf("0\n");
}
}
printf("\n");
}
}