POJ 2155 Matrix二维树状数组+YY(区间更新,单点查询)
Posted ymzjj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2155 Matrix二维树状数组+YY(区间更新,单点查询)相关的知识,希望对你有一定的参考价值。
题目链接:http://poj.org/problem?id=2155
Matrix
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 32950 | Accepted: 11943 |
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].
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.
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.
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
题意概括:
有一个初始值为0的N*N的二维矩阵,有T次操作,每次操作有两种选择:
C : 修改以(x1, y1)为左上角(x2, y2)为右下角的矩阵的值(0和1互换)
Q:查询(x, y)的值为 0 或者 为 1;
解题思路:
涉及到多次区间修改和区间查询的优先考虑线段树和树状数组,这道题巧妙之处在于灵活运用树状数组的前缀和,把区间修改转换单点修改,一维需要标记两个点而二维需要标记四个点,一个点用于发挥效果,另外三个点用于消除效果,因为树状数组维护的是前缀和,而对于二维树状数组,查询的则是以(1,1)为左上角,(x,y)为右下角的矩阵的和。
第二就是我们可以借助修改次数的奇偶性来判断该点的值为 0 / 1;
例如:N = 3;C:x1 = 1, y1 = 1, x2 = 2, y2 = 2;
1 | 1 | |
(x,y) | ||
1 | 1 |
(因为我们只需要知道奇偶性,所以矩阵外的点加1即可消除效果)
AC code:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define ll long long int; 7 #define INF 0x3f3f3f3f 8 using namespace std; 9 const int MAXN = 1e3+10; 10 11 int mmp[MAXN][MAXN]; 12 int N, T; 13 14 int lowbit(int x) 15 { 16 return x&(-x); 17 } 18 19 void add(int x, int y, int value) 20 { 21 for(int i = x; i <= N; i += lowbit(i)) 22 for(int j = y; j <= N; j += lowbit(j)) 23 mmp[i][j]+=value; 24 } 25 26 int sum(int x, int y) 27 { 28 int res = 0; 29 for(int i = x; i > 0; i -= lowbit(i)) 30 for(int j = y; j > 0; j -= lowbit(j)) 31 res+=mmp[i][j]; 32 return res; 33 } 34 35 void init() 36 { 37 for(int i = 0; i <= N; i++) 38 for(int j = 0; j <= N; j++) 39 mmp[i][j] = 0; 40 } 41 42 int main() 43 { 44 int T_case; 45 char com[3]; 46 int x, y, x1, x2, y1, y2; 47 scanf("%d", &T_case); 48 while(T_case--) 49 { 50 scanf("%d%d", &N, &T); 51 init(); 52 while(T--) 53 { 54 scanf("%s", &com); 55 if(com[0] == ‘C‘) 56 { 57 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 58 add(x1, y1, 1); 59 add(x2+1, y1, 1); 60 add(x1, y2+1, 1); 61 add(x2+1, y2+1, 1); 62 } 63 else if(com[0] == ‘Q‘) 64 { 65 scanf("%d%d", &x, &y); 66 int res = 0; 67 res = sum(x, y); 68 // printf("res: %d ", res); 69 if(res%2) printf("1 "); 70 else printf("0 "); 71 } 72 } 73 puts(""); 74 } 75 return 0; 76 }
以上是关于POJ 2155 Matrix二维树状数组+YY(区间更新,单点查询)的主要内容,如果未能解决你的问题,请参考以下文章
POJ - 2155 Matrix (二维树状数组 + 区间改动 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)