POJ 2155 Matrix
题目链接:
解题思路:首先考虑一维的情况,更改某个区间[l, r]时相当于l出加一,r + 1除减一,这样就能保证每次计算的时候两者总是能抵消的。当然也可以在l与r + 1除都加一,而每次求和之后mod 2。
接下来考虑二维,更改区间[x1, y1], [x2, y2]的时候,只需在(x1, y1), (x1, y2 + 1), (x2 + 1, y1), (x2 + 1, y2 + 1)四个点除加一即可(好吧其实我只推出了一维,二维是看别人博客的)。然后求和就交给二维树状数组了。
比较有意思的是,当一个函数这样写的时候
1 void add(int i, int j, int val){ 2 for(i; i <= n; i += lowbit(i)){ 3 for(j; j <= n; j += lowbit(j)){ 4 bit[i][j] += val; 5 } 6 } 7 }
得到的结果竟然是错误的,不知道是什么bug。
代码:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 #include <cstring> 6 #include <cassert> 7 #include <cstdio> 8 #include <cctype> 9 #include <vector> 10 #include <string> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <map> 15 #include <set> 16 using namespace std; 17 #define rep(i,a,n) for (int i=a;i<n;i++) 18 #define per(i,a,n) for (int i=n-1;i>=a;i--) 19 #define pb push_back 20 #define mp make_pair 21 #define all(x) (x).begin(),(x).end() 22 #define fi first 23 #define se second 24 #define SZ(x) ((int)(x).size()) 25 typedef vector<int> VI; 26 typedef long long ll; 27 typedef pair<int, int> PII; 28 const ll mod = 1000000007; 29 ll powmod(ll a, ll b) { ll res = 1; a %= mod; assert(b >= 0); for (; b; b >>= 1) { if (b & 1)res = res*a%mod; a = a*a%mod; }return res; } 30 // head 31 const int inf = 0x3f3f3f3f; 32 const int maxn = 1010; 33 34 int bit[maxn][maxn], n; 35 36 int lowbit(int x){ 37 return x & (-x); 38 } 39 int sum(int x, int y){ 40 int ans = 0; 41 for(int i = x; i > 0; i -= lowbit(i)){ 42 for(int j = y ; j > 0; j -= lowbit(j)){ 43 ans += bit[i][j]; 44 } 45 } 46 return ans; 47 } 48 void add(int x, int y, int val){ 49 for(int i = x; i <= n; i += lowbit(i)){ 50 for(int j = y; j <= n; j += lowbit(j)){ 51 bit[i][j] += val; 52 } 53 } 54 } 55 56 int main(){ 57 int T; 58 scanf("%d", &T); 59 while(T--){ 60 memset(bit, 0, sizeof(bit)); 61 int m; 62 scanf("%d %d", &n, &m); 63 while(m--){ 64 char ch; 65 scanf(" %c", &ch); 66 if(ch == 'C'){ 67 int x1, y1, x2, y2; 68 scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 69 70 add(x1, y1, 1); 71 add(x2 + 1, y1, 1); 72 add(x1, y2 + 1, 1); 73 add(x2 + 1, y2 + 1, 1); 74 75 } 76 else{ 77 int x1, y1; 78 scanf("%d %d", &x1, &y1); 79 if(sum(x1, y1) % 2 == 0) puts("0"); 80 else puts("1"); 81 } 82 } 83 if(T) 84 puts(""); 85 } 86 }
题目:
Matrix
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 28786 | Accepted: 10494 |
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