码迷,mamicode.com
首页 > 编程语言 > 详细

POJ 2155 Matrix【二维树状数组+YY(区间更新,单点查询)】

时间:2018-08-12 22:49:08      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:nta   二维矩阵   lang   script   height   center   维护   printf   技术分享   

题目链接: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]. 

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

 

题意概括:

有一个初始值为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\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(区间更新,单点查询)】

标签:nta   二维矩阵   lang   script   height   center   维护   printf   技术分享   

原文地址:https://www.cnblogs.com/ymzjj/p/9465282.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!