题意:基于矩阵的NIM游戏,求异或和。
思路:在x1,y1 到 x2, y2的异或和 = A[ x2 ][ y2 ] ^ A[x1-1][ y2 ] ^ A[ x2 ][y1 - 1] ^ A[ x1-1 ][ y1 - 1 ]
先普通来了两次,结果都超时。 上个二维树状数组AC
#include <cstdio> #include <cstring> #define MAXN 100010 using namespace std; int a[505][505]; int sum[505][505]; int n,m,qq; int lowbit(int x) { return x&(-x); } void inser(int x,int y,int k) { for(int i = x; i <= n; i+=lowbit(i)) for(int j = y; j <= m; j+=lowbit(j)) { sum[i][j] ^= k; } } int query(int x,int y) { int ans = 0; for(int i = x; i >= 1; i-=lowbit(i)) for(int j = y; j >= 1; j-=lowbit(j)) { ans ^= sum[i][j]; } return ans; } int main() { int T; scanf("%d",&T); while(T--) { int q; scanf("%d%d%d",&n,&m,&q); memset(sum,0,sizeof(sum)); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { scanf("%d",&a[i][j]); inser(i,j,a[i][j]); } for(int i = 1; i <= q; i++) { int qq,x1,y1,x2,y2,tt; scanf("%d",&qq); if(qq == 1) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int ans = 0; ans ^= query(x2, y2); if(y1 > 1) ans ^= query(x2, y1 - 1); if(x1 > 1) ans ^= query(x1 - 1, y2); if(x1 > 1 && y1 > 1) ans ^= query(x1 - 1, y1 - 1); if(ans) printf("Yes "); else printf("No "); } else { scanf("%d%d%d",&x1,&y1,&tt); inser(x1,y1,a[x1][y1]^tt); a[x1][y1] = tt; } } } return 0; }