题意: 给出一个矩形的左上角和右下角(类似于矩阵), 被矩形框住的点需要改变它的值(0,1),给出一些操作,要求输出某点的值。
本题是改变区域而求点。以二维树状数组来记录某点的改变次数。先想想一维数组,例如 c[1], c[2] , c[3], c[4], c[5], ....c[10], 假设要改变c[3]-c[5]间的区域,只需要把c[3]改变一次(它后面的点全都随之改变一次), 然后再将c[6]改变一次,这样的话,c[6]及其后面的点改变了两次,即相当于不变。
#include <iostream>
using namespace std;
int c[1010][1010], n;
int lowbit ( int x )
{
return x & ( -x );
}
void modify ( int x, int y )
{
for ( int i = x; i <= n; i += lowbit(i) )
{
for ( int j = y; j <= n; j += lowbit(j) )
c[i][j]++;
}
}
void update ( int x1, int y1, int x2, int y2 )
{
modify ( x1, y1 );
modify ( x2 + 1, y2 + 1 );
modify ( x1, y2 + 1 );
modify ( x2 + 1, y1 );
}
int sum ( int x, int y )
{
int total = 0;
for ( int i = x; i > 0; i -= lowbit(i) )
{
for ( int j = y; j > 0; j -= lowbit(j) )
total += c[i][j];
}
return total;
}
int main()
{
int t, q, x1, y1, x2, y2;
char oper[5];
scanf("%d",&t);
while ( t-- )
{
scanf("%d%d",&n,&q);
memset(c,0,sizeof(c));
while ( q-- )
{
scanf("%s",oper);
if ( oper[0] == 'C' )
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update ( x1, y1, x2, y2 );
}
if ( oper[0] == 'Q' )
{
scanf("%d%d",&x1,&y1);
printf("%d\n", sum ( x1, y1 ) % 2 );
}
}
putchar('\n');
}
return 0;
}