POJ2155 Matrix

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 25843   Accepted: 9545

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改成1,1改成0。这里等价成每次值+1,求解时%2

二维线段树的标记无法下传,解决方法是标记永久化,求值时,累积树上每一层的标记。

RE了好久,发现是边界写错了……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define ls l,mid,rt<<1
 6 #define rs mid+1,r,rt<<1|1
 7 using namespace std;
 8 const int mxn=4020;
 9 int t[mxn][mxn];
10 int n,m;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
15     return x*f;
16 }
17 void updateY(int L,int R,int v,int l,int r,int rt,int px){
18 //    printf("UY:L:%d R:%d  v:%d   %d %d %d %d
",L,R,v,l,r,rt,px);
19     if(L<=l && r<=R){
20         t[px][rt]+=v;return;
21     }
22     int mid=(l+r)>>1;
23     if(L<=mid)updateY(L,R,v,ls,px);
24     if(R>mid)updateY(L,R,v,rs,px);
25     return;
26 }
27 void updateX(int L,int R,int yy1,int yy2,int v,int l,int r,int rt){
28     if(L<=l && r<=R){
29         updateY(yy1,yy2,v,1,n,1,rt);return;
30     }
31     int mid=(l+r)>>1;
32     if(L<=mid)updateX(L,R,yy1,yy2,v,ls);
33     if(R>mid)updateX(L,R,yy1,yy2,v,rs);
34      return;
35 }
36 int qY(int y,int l,int r,int rt,int px){
37     if(l==r){return t[px][rt];}
38     int mid=(l+r)>>1;
39     if(y<=mid)return t[px][rt]+qY(y,ls,px);
40     else return t[px][rt]+qY(y,rs,px);
41 }
42 int qX(int x,int y,int l,int r,int rt){
43     int res=qY(y,1,n,1,rt);
44     if(l==r)return res;
45     int mid=(l+r)>>1;
46     if(x<=mid)return res+qX(x,y,ls);
47     else return res+qX(x,y,rs);
48 }
49 int main(){
50     int T=read();
51     int i,j;
52     int x1,x2,yy1,yy2;
53     while(T--){
54         memset(t,0,sizeof t);
55         //
56         n=read();m=read();
57         char op[3];
58         while(m--){
59             scanf("%s",op);
60             if(op[0]=='C'){
61                 x1=read(),yy1=read(),x2=read(),yy2=read();
62                 updateX(x1,x2,yy1,yy2,1,1,n,1);
63             }
64             else{
65                 int x1=read(),yy1=read();
66                 int ans=qX(x1,yy1,1,n,1);
67                 if(ans&1)printf("1
");
68                 else printf("0
");
69             }
70         }
71         printf("
");
72     }
73     return 0;
74 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6341514.html