http://poj.org/problem?id=2155
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 12894 | Accepted: 4834 |
Description
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 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
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
给一个N*N的矩阵,每次给一个命令取反一个子矩阵,或者查询其中某一点的01状态。(注意每两组output中间要空行,PE了一次)
解题方法;
二维线段树。
二维线段树确实不会用,而且理解的不深啊。。。。
解题小结:
原先好像写过二维的线段树,不过都忘得差不多了,这一次算是重新捡起来吧。
这一道题可以用a[rootx][rooty]来记录rootx段到rooty段是否取反,rootx指向行里的一段,rooty指向列里的一段,那么[rootx][rooty]就自然是一个子矩阵了。
最后求(x,y)是否取反,就是一路遍历所有包含x,y的矩阵,记录一下一共取反了多少次(Discuss里说用异或,很不错哈~)
这一题更新和查询都写成x,y版本的,x版本套y版本,就解二维的问题了。
例如在Modify_x里套用Modify_y。
#include
#include
#include
#define maxn 1010
int a[4*maxn][4*maxn];
int ans;
void Modify_y(int rootx, int rooty, int l, int r, int y1, int y2)
{
}
void Modify_x(int rootx, int n, int l, int r, int x1, int x2, int y1, int y2)
{
}
void Query_y(int rootx, int rooty, int l, int r, int y)
{
}
void Query_x(int rootx, int n, int l, int r, int x, int y)
{
}
int main()
{
}