因为xor具有前缀和性质,所以可以建立一颗二维树状数组,写起来只是稍微有点改变,感觉此题还是很不错的,结合了数据结构和博弈。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 501; 7 int a[N][N]; 8 int c[N][N]; 9 int n, m, q; 10 11 int lb( int i ) 12 { 13 return i & -i; 14 } 15 16 void update( int i, int j, int val ) 17 { 18 for ( int ii = i; ii <= n; ii += lb(ii) ) 19 { 20 for ( int jj = j; jj <= m; jj += lb(jj) ) 21 { 22 c[ii][jj] ^= val; 23 } 24 } 25 } 26 27 int sum( int i, int j ) 28 { 29 int res = 0; 30 for ( int ii = i; ii > 0; ii -= lb(ii) ) 31 { 32 for ( int jj = j; jj > 0; jj -= lb(jj) ) 33 { 34 res ^= c[ii][jj]; 35 } 36 } 37 return res; 38 } 39 40 int query( int x1, int y1, int x2, int y2 ) 41 { 42 int p = sum( x2, y2 ); 43 int q = sum( x1 - 1, y2 ); 44 int r = sum( x2, y1 - 1 ); 45 int s = sum( x1 - 1, y1 - 1 ); 46 return p ^ q ^ r ^ s; 47 } 48 49 int main () 50 { 51 int t; 52 scanf("%d", &t); 53 while ( t-- ) 54 { 55 scanf("%d%d%d", &n, &m, &q); 56 memset( a, 0, sizeof(a) ); 57 memset( c, 0, sizeof(c) ); 58 for ( int i = 1; i <= n; i++ ) 59 { 60 for ( int j = 1; j <= m; j++ ) 61 { 62 scanf("%d", &a[i][j]); 63 update( i, j, a[i][j] ); 64 } 65 } 66 while ( q-- ) 67 { 68 int opt; 69 scanf("%d", &opt); 70 if ( opt == 1 ) 71 { 72 int x1, y1, x2, y2; 73 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 74 if ( query( x1, y1, x2, y2 ) ) 75 { 76 puts("Yes"); 77 } 78 else 79 { 80 puts("No"); 81 } 82 } 83 else 84 { 85 int x, y, z; 86 scanf("%d%d%d", &x, &y, &z); 87 update( x, y, a[x][y] ^ z ); 88 a[x][y] = z; 89 } 90 } 91 } 92 return 0; 93 }
时间: 2024-12-17 17:47:33