標籤:nta 二維矩陣 lang script height center 維護 printf 技術分享
題目連結:http://poj.org/problem?id=2155
Matrix
| Time Limit: 3000MS |
|
Memory Limit: 65536K |
| Total Submissions: 32950 |
|
Accepted: 11943 |
DescriptionGiven 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]. InputThe 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. OutputFor 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
12 10C 2 1 2 2Q 2 2C 2 1 2 1Q 1 1C 1 1 2 1C 1 2 1 2C 1 1 2 2Q 1 1C 1 1 2 1Q 2 1
Sample Output
1001
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即可消除效果)
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\n", res);69 if(res%2) printf("1\n");70 else printf("0\n");71 }72 }73 puts("");74 }75 return 0;76 }View Code
POJ 2155 Matrix【二維樹狀數組+YY(區間更新,單點查詢)】