ACM: 树状数组 poj 2155 学习《浅…
2016-05-19 23:24
519 查看
Matrix
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
题意: 一个矩阵中状态只有0和1,两种操作:
修改:
子矩阵:(x1,y1,x2,y2)每次改变一个子矩阵的状态(反转0->1,1->0);
查询: 每次查询具体某个(x,y)
解题思路:
1.
看了大牛的解题论文如梦初醒, 因为修改区间矩阵的状态, 可以用树状数组的特性修改,
如图:
![](http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif)
同过修改子矩阵的值,
由于判断0,1用奇偶判断即可, 每次修改都要有四个区域的修改.
这样保证只修改(x1,y1,x2,y2)子矩阵. (修改偶数次相当于不变, 负数不影响奇偶性);
2. 查询只要直接求子矩阵范围的奇偶性即可. (用笔在纸上画一画最清楚).
3.
《浅谈信息学竞赛中的“0”和“1”》文章内有详细解释. 学习别人的好方法也是一种学习
方法. 集大家之所长.
代码:
#include
<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 1005
int n, T;
int c[MAX][MAX];
int x1, y1, x2, y2;
int result;
char ch[2];
inline int lowbit(int x)
{
return x & (-x);
}
void update(int x, int y, int val)
{
int i, j;
for(i = x; i <= n; i +=
lowbit(i))
{
for(j = y; j <=
n; j += lowbit(j))
c[i][j] +=
val;
}
}
int getSum(int x, int y)
{
int sum = 0;
int i, j;
for(i = x; i > 0; i -=
lowbit(i))
{
for(j = y; j >
0; j -= lowbit(j))
sum +=
c[i][j];
}
return sum;
}
int main()
{
// freopen("input.txt", "r", stdin);
int caseNum, i;
scanf("%d",&caseNum);
while(caseNum--)
{
memset(c, 0, sizeof(c));
scanf("%d
%d",&n, &T);
for(i = 0; i <
T; ++i)
{
scanf("%s",ch);
if(ch[0] ==
'C')
{
scanf("%d
%d %d %d",&x1, &y1,
&x2, &y2);
update(x1,
y1, 1);
update(x2+1,
y1, -1);
update(x1,
y2+1, -1);
update(x2+1,
y2+1, -1);
}
else if(ch[0]
== 'Q')
{
scanf("%d
%d",&x1, &y1);
result
= getSum(x1, y1);
printf("%d\n",1&result);
}
}
if(caseNum != 0)
printf("\n");
}
return 0;
}
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
题意: 一个矩阵中状态只有0和1,两种操作:
修改:
子矩阵:(x1,y1,x2,y2)每次改变一个子矩阵的状态(反转0->1,1->0);
查询: 每次查询具体某个(x,y)
解题思路:
1.
看了大牛的解题论文如梦初醒, 因为修改区间矩阵的状态, 可以用树状数组的特性修改,
如图:
![](http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif)
同过修改子矩阵的值,
由于判断0,1用奇偶判断即可, 每次修改都要有四个区域的修改.
这样保证只修改(x1,y1,x2,y2)子矩阵. (修改偶数次相当于不变, 负数不影响奇偶性);
2. 查询只要直接求子矩阵范围的奇偶性即可. (用笔在纸上画一画最清楚).
3.
《浅谈信息学竞赛中的“0”和“1”》文章内有详细解释. 学习别人的好方法也是一种学习
方法. 集大家之所长.
代码:
#include
<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 1005
int n, T;
int c[MAX][MAX];
int x1, y1, x2, y2;
int result;
char ch[2];
inline int lowbit(int x)
{
return x & (-x);
}
void update(int x, int y, int val)
{
int i, j;
for(i = x; i <= n; i +=
lowbit(i))
{
for(j = y; j <=
n; j += lowbit(j))
c[i][j] +=
val;
}
}
int getSum(int x, int y)
{
int sum = 0;
int i, j;
for(i = x; i > 0; i -=
lowbit(i))
{
for(j = y; j >
0; j -= lowbit(j))
sum +=
c[i][j];
}
return sum;
}
int main()
{
// freopen("input.txt", "r", stdin);
int caseNum, i;
scanf("%d",&caseNum);
while(caseNum--)
{
memset(c, 0, sizeof(c));
scanf("%d
%d",&n, &T);
for(i = 0; i <
T; ++i)
{
scanf("%s",ch);
if(ch[0] ==
'C')
{
scanf("%d
%d %d %d",&x1, &y1,
&x2, &y2);
update(x1,
y1, 1);
update(x2+1,
y1, -1);
update(x1,
y2+1, -1);
update(x2+1,
y2+1, -1);
}
else if(ch[0]
== 'Q')
{
scanf("%d
%d",&x1, &y1);
result
= getSum(x1, y1);
printf("%d\n",1&result);
}
}
if(caseNum != 0)
printf("\n");
}
return 0;
}
相关文章推荐
- ACM: 树状数组 poj 1195
- ACM: 线段树 poj 2482 煽情的情书!…
- C++ 友元类
- ACM: 线段树 poj 3277
- ACM: 线段树 poj 3468
- ACM: 线段树 poj 2886 约瑟夫问题
- ACM: 线段树 poj 2777 继续熟练线…
- 协同开发时, 如何合并不稳定的联调代码?
- ACM: 线段树 poj 2828 认真对待每…
- ACM: trie树 poj 2513
- 计算机和资料 转载
- 凌宇的项目之旅-关于自定义锁屏
- Jmeter文章索引贴
- codeforces 675C C. Money Transfers(贪心)
- ACM: 线段树 poj 1177
- ACM: 线段树 poj 1151 足足想了三…
- ACM: 线段树 poj 2352
- ACM: 最小堆 poj 2274 思路清晰, …
- ACM: 最小堆 poj 2227 最小堆 fro…
- ACM: 划分树 poj 2761 在poj2104基…