POJ2155 Matrix (二维线段树)

POJ2155 Matrix (二维线段树)

写了题还是应该来总结一下,否则除了个别刻骨铭心的题以外,都忘掉了。

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==&& 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==&& x2==r){
28        Modify_y(rootx, 11, 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, 11, 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, 0sizeof(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

你可能感兴趣的:(POJ2155 Matrix (二维线段树))