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==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
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