# POJ 2155 Matrix(二维树状数组，绝对详细)

1518人阅读 评论(0)

Matrix
 Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20599 Accepted: 7673

Description

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N).

We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions.

1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2).
2. Q x y (1 <= x, y <= n) querys A[x, y].

Input

The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case.

The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above.

Output

For each querying output one line, which has an integer representing A[x, y].

There is a blank line between every two continuous test cases.

Sample Input

1
2 10
C 2 1 2 2
Q 2 2
C 2 1 2 1
Q 1 1
C 1 1 2 1
C 1 2 1 2
C 1 1 2 2
Q 1 1
C 1 1 2 1
Q 2 1


Sample Output

1
0
0
1


Source

POJ Monthly,Lou Tiancheng

先举个一维的例子：你要使区间[x,y]全部加上一个值v,结合树状数组的功能，可以类似扫气球那样，在x处加v, y+1处减1

这样如果你要求x处的值，就转换成求[1,x]的和了，例如 ：一个n=6的数组，一开始为0  0  0   0  0  0

在[2,4]加上2后变成   0   2   0   0   -2    0  这样前缀和 sum[1]=0;sum[2]=2;sum[3]=2;sum[4]=2;sum[5]=0;sum[6]=0;

依次代表了每个数的值。

二维的也一样，因为二维树状数组的getsum(int x,int y)函数是求矩阵（1,1）~(x,y)的值得和，也就类似于前缀和，原理和一维的一样

只不过线操作改成了平面操作，自己可以画个图感受下。

即：

然后查询单点就是求和了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define N 1040
#define ll long long

using namespace std;

int n;

int bit[N][N];

int sum(int i,int j) {
int s=0;
while(i>0) {
int jj=j;
while(jj>0) {
s+=bit[i][jj];
jj-=jj&-jj;
}
i-=i&-i;
}
return s;
}

void add(int i,int j,int x) {
while(i<=n) {
int jj=j;
while(jj<=n) {
bit[i][jj]+=x;
jj+=jj&-jj;
}
i+=i&-i;
}
}

int main() {
freopen("test.in","r",stdin);
int t;
cin>>t;
while(t--) {
int q;
scanf("%d%d ",&n,&q);
memset(bit,0,sizeof bit);
char c;
int x,y,x1,y1;
while(q--) {
scanf("%c",&c);
if(c=='C') {
scanf("%d%d%d%d",&x,&y,&x1,&y1);
} else {
scanf("%d%d",&x,&y);
printf("%d\n",sum(x,y)%2);
}
getchar();
}
if(t)printf("\n");
}
return 0;
}


2
1

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：144666次
• 积分：4341
• 等级：
• 排名：第6934名
• 原创：294篇
• 转载：16篇
• 译文：0篇
• 评论：13条
文章分类
阅读排行
最新评论