题目链接:
http://poj.org/problem?id=2155
题意:
给出N*N的矩阵,初始为0。
给出矩阵左上角和右下角坐标,这个面积范围里的元素 1变0 ,0 变1,然后给出询问,问某个点是多少。
题解:
http://blog.csdn.net/zxy_snow/article/details/6264135
我们将1变0,0变1转变为将这一块面积翻转几次,奇数次就是1,偶数次就是0。
二维数组维护面积,加加减减。。
add(x2,y2);
add(x1-1,y2);
add(x2,y1-1);
add(x1-1,y1-1);
看图:虽然非常丑,对于翻转一块面积,先翻转整体,减掉多加的,加上多减的,图上的数字代表这块面积翻转了几次,偶数次代表没有改变嘛。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 typedef long long ll; 7 #define MS(a) memset(a,0,sizeof(a)) 8 #define MP make_pair 9 #define PB push_back 10 const int INF = 0x3f3f3f3f; 11 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 12 inline ll read(){ 13 ll x=0,f=1;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 ////////////////////////////////////////////////////////////////////////// 19 const int maxn = 1e3+10; 20 21 int bit[maxn][maxn]; 22 23 void add(int x,int y){ 24 for(int i=x; i<maxn; i+=i&-i) 25 for(int j=y; j<maxn; j+=j&-j) 26 bit[i][j]++; 27 } 28 29 int sum(int x,int y){ 30 int res = 0; 31 for(int i=x; i>0; i-=i&-i) 32 for(int j=y; j>0; j-=j&-j) 33 res += bit[i][j]; 34 return res; 35 } 36 37 int main(){ 38 int T = read(); 39 while(T--){ 40 MS(bit); 41 int n,k; 42 cin >> n >> k; 43 for(int i=0; i<k; i++){ 44 char op; scanf(" %c",&op); 45 if(op == 'C'){ 46 int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 47 x1++,y1++,x2++,y2++; 48 add(x2,y2); 49 add(x1-1,y1-1); 50 add(x1-1,y2); 51 add(x2,y1-1); 52 }else { 53 int x,y; scanf("%d%d",&x,&y); 54 cout << sum(x,y)%2 << endl; 55 } 56 } 57 puts(""); 58 } 59 60 return 0; 61 }