写了题还是应该来总结一下,否则除了个别刻骨铭心的题以外,都忘掉了。
POJ2155 题目大意: 给一个N*N的矩阵,每次给一个命令取反一个子矩阵,或者查询其中某一点的01状态。(注意每两组output中间要空行,PE了一次)
解题方法; 二维线段树。
解题小结: 原先好像写过二维的线段树,不过都忘得差不多了,这一次算是重新捡起来吧。 这一道题可以用a[rootx][rooty]来记录rootx段到rooty段是否取反,rootx指向行里的一段,rooty指向列里的一段,那么[rootx][rooty]就自然是一个子矩阵了。 最后求(x,y)是否取反,就是一路遍历所有包含x,y的矩阵,记录一下一共取反了多少次(Discuss里说用异或,很不错哈~) 这一题更新和查询都写成x,y版本的,x版本套y版本,就解二维的问题了。 例如在Modify_x里套用Modify_y。
POJ2155 1#include <cstdio> 2#include <cstdlib> 3#include <cstring> 4#define maxn 1010 5 6int a[4*maxn][4*maxn]; 7int ans; 8 9void Modify_y(int rootx, int rooty, int l, int r, int y1, int y2){ 10 if (y1==l && y2==r){ 11 a[rootx][rooty]=!a[rootx][rooty]; 12 } 13 else{ 14 int mid=(l+r)>>1; 15 if (y2<=mid) 16 Modify_y(rootx, (rooty<<1), l, mid, y1, y2); 17 else if (y1>mid) 18 Modify_y(rootx, (rooty<<1)+1, mid+1, r, y1, y2); 19 else{ 20 Modify_y(rootx, (rooty<<1), l, mid, y1, mid); 21 Modify_y(rootx, (rooty<<1)+1, mid+1, r, mid+1, y2); 22 } 23 } 24} 25 26void Modify_x(int rootx, int n, int l, int r, int x1, int x2, int y1, int y2){ 27 if (x1==l && x2==r){ 28 Modify_y(rootx, 1, 1, n, y1, y2); 29 } 30 else{ 31 int mid=(l+r)>>1; 32 33 if (x2<=mid) 34 Modify_x((rootx<<1), n, l, mid, x1, x2, y1, y2); 35 else if (x1>mid) 36 Modify_x((rootx<<1)+1, n, mid+1, r, x1, x2, y1, y2); 37 else{ 38 Modify_x((rootx<<1), n, l, mid, x1, mid, y1, y2); 39 Modify_x((rootx<<1)+1, n, mid+1, r, mid+1, x2, y1, y2); 40 } 41 } 42} 43 44void Query_y(int rootx, int rooty, int l, int r, int y){ 45 ans^=a[rootx][rooty]; 46 if (l<r){ 47 int mid=(l+r)>>1; 48 if (y<=mid) 49 Query_y(rootx, (rooty<<1), l, mid, y); 50 else 51 Query_y(rootx, (rooty<<1)+1, mid+1, r, y); 52 } 53} 54 55void Query_x(int rootx, int n, int l, int r, int x, int y){ 56 Query_y(rootx, 1, 1, n, y); 57 if (l<r){ 58 int mid=(l+r)>>1; 59 if (x<=mid) 60 Query_x((rootx<<1), n, l, mid, x, y); 61 else 62 Query_x((rootx<<1)+1, n, mid+1, r, x, y); 63 } 64} 65 66int main(){ 67 int cases, n, t, x1, x2, y1, y2; 68 char ch[5]; 69 scanf("%d", &cases); 70 for (int cs=1; cs<=cases; cs++){ 71 if (cs!=1) printf("\n"); 72 scanf("%d%d", &n, &t); 73 memset(a, 0, sizeof(a)); 74 while (t--){ 75 scanf("%s", ch); 76 if (ch[0]=='C'){ 77 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 78 Modify_x(1, n, 1, n, x1, x2, y1, y2); 79 } 80 else{ 81 ans=0; 82 scanf("%d%d", &x1, &y1); 83 Query_x(1, n, 1, n, x1, y1); 84 printf("%d\n", ans); 85 } 86 } 87 } 88 return 0; 89} 90
|