[POJ2155] Matrix(二维线段树,树套树)

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POJ2155] Matrix(二维线段树,树套树)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=2155

题意:给一个01矩阵,两个操作,翻转:子矩阵里每一个数都由0变1,1变0。 查询:查询某一点是0还是1。

一直以为二维线段树就是开一个线段树数组的我…

这题暴力更新每一个小矩形,翻转就+1,最后看看某点的奇偶。

写屎了,特别注意的是在外层查询的时候要先把当前层的内层query掉,接着再向下扩展。这样外层就不用lazy啦

 

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <cassert>
  8 #include <cstdio>
  9 #include <bitset>
 10 #include <vector>
 11 #include <deque>
 12 #include <queue>
 13 #include <stack>
 14 #include <ctime>
 15 #include <set>
 16 #include <map>
 17 #include <cmath>
 18 using namespace std;
 19 
 20 #define lrt rt << 1
 21 #define rrt rt << 1 | 1
 22 const int maxn = 1010;
 23 
 24 typedef struct NodeY {
 25     int val, sign;
 26 }NodeY;
 27 
 28 typedef struct NodeX {
 29     NodeY segY[maxn<<2];
 30 
 31     void build(int l, int r, int rt) {
 32         segY[rt].val = segY[rt].sign = 0;
 33         if(l == r) return;
 34         int mid = (l + r) >> 1;
 35         build(l, mid, lrt);
 36         build(mid+1, r, rrt);
 37     }
 38 
 39     void pushdown(int l, int r, int rt) {
 40         if(segY[rt].sign) {
 41             int mid = (l + r) >> 1;
 42             segY[lrt].sign += segY[rt].sign;
 43             segY[rrt].sign += segY[rt].sign;
 44              segY[lrt].val += (mid - l + 1) * segY[rt].sign;
 45             segY[rrt].val += (r - mid) * segY[rt].sign;
 46             segY[rt].sign = 0;
 47         }
 48     }
 49 
 50     void update(int L, int R, int l, int r, int rt) {
 51         if(L <= l && r <= R) {
 52             segY[rt].sign++;
 53             segY[rt].val += (r - l + 1);
 54             return;
 55         }
 56         pushdown(l, r, rt);
 57         int mid = (l + r) >> 1;
 58         if(L <= mid) update(L, R, l, mid, lrt);
 59         if(mid < R) update(L, R, mid+1, r, rrt);
 60     }
 61 
 62     int query(int pos, int l, int r, int rt) {
 63         if(l == r) return segY[rt].val;
 64         pushdown(l, r, rt);
 65         int mid = (l + r) >> 1;
 66         int ret = 0;
 67         if(pos <= mid) ret += query(pos, l, mid, lrt);
 68         else ret += query(pos, mid+1, r, rrt);
 69         return ret;
 70     }
 71 }NodeX;
 72 
 73 int n, q;
 74 NodeX segX[maxn<<2];
 75 
 76 void build(int l, int r, int rt) {
 77     segX[rt].build(1, n, 1);
 78     if(l == r) return;
 79     int mid = (l + r) >> 1;
 80     build(l, mid, lrt);
 81     build(mid+1, r, rrt);
 82 }
 83 
 84 void update(int yl, int yr, int L, int R, int l, int r, int rt) {
 85     if(L <= l && r <= R) {
 86         segX[rt].update(yl, yr, 1, n, 1);
 87         return;
 88     }
 89     int mid = (l + r) >> 1;
 90     if(L <= mid) update(yl, yr, L, R, l, mid, lrt);
 91     if(mid < R) update(yl, yr, L, R, mid+1, r, rrt);
 92 }
 93 
 94 int query(int x, int y, int l, int r, int rt) {
 95     int ret = segX[rt].query(y, 1, n, 1);
 96     if(l == r) return ret;
 97     int mid = (l + r) >> 1;
 98     if(x <= mid) ret += query(x, y, l, mid, lrt);
 99     else ret += query(x, y, mid+1, r, rrt);
100     return ret;
101 }
102 
103 char op[3];
104 int xa, ya, xb, yb;
105 
106 int main() {
107     // freopen("in", "r", stdin);
108     int T;
109     scanf("%d", &T);
110     while(T--) {
111         scanf("%d%d",&n,&q);
112         build(1, n, 1);
113         while(q--) {
114             scanf("%s", op);
115             if(op[0] == C) {
116                 scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
117                 update(ya, yb, xa, xb, 1, n, 1);
118             }
119             else {
120                 scanf("%d%d",&xa,&ya);
121                 printf("%d\n", query(xa, ya, 1, n, 1) % 2);
122             }
123         }
124         printf("\n");
125     }
126     return 0;
127 }

 

按位翻转也可以,不过要加个pushdown:

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <cassert>
  8 #include <cstdio>
  9 #include <bitset>
 10 #include <vector>
 11 #include <deque>
 12 #include <queue>
 13 #include <stack>
 14 #include <ctime>
 15 #include <set>
 16 #include <map>
 17 #include <cmath>
 18 using namespace std;
 19 
 20 #define lrt rt << 1
 21 #define rrt rt << 1 | 1
 22 const int maxn = 1010;
 23 
 24 typedef struct NodeY {
 25     bool sign;
 26 }NodeY;
 27 
 28 typedef struct NodeX {
 29     NodeY segY[maxn<<2];
 30     void build(int l, int r, int rt) {
 31         segY[rt].sign = 0;
 32         if(l == r) return;
 33         int mid = (l + r) >> 1;
 34         build(l, mid, lrt);
 35         build(mid+1, r, rrt);
 36     }
 37     void pushdown(int rt) {
 38         if(segY[rt].sign) {
 39             segY[lrt].sign ^= 1; segY[rrt].sign ^= 1;
 40             segY[rt].sign = 0;
 41         }
 42     }
 43     void update(int L, int R, int l, int r, int rt) {
 44         if(L <= l && r <= R) {
 45             segY[rt].sign ^= 1;
 46             return;
 47         }
 48         pushdown(rt);
 49         int mid = (l + r) >> 1;
 50         if(L <= mid) update(L, R, l, mid, lrt);
 51         if(mid < R) update(L, R, mid+1, r, rrt);
 52     }
 53     int query(int pos, int l, int r, int rt) {
 54         if(l == r) return segY[rt].sign;
 55         pushdown(rt);
 56         int mid = (l + r) >> 1;
 57         if(pos <= mid) return query(pos, l, mid, lrt);
 58         else return query(pos, mid+1, r, rrt);
 59     }
 60 }NodeX;
 61 
 62 int n, q;
 63 NodeX segX[maxn<<2];
 64 
 65 void build(int l, int r, int rt) {
 66     segX[rt].build(1, n, 1);
 67     if(l == r) return;
 68     int mid = (l + r) >> 1;
 69     build(l, mid, lrt);
 70     build(mid+1, r, rrt);
 71 }
 72 
 73 void update(int yl, int yr, int L, int R, int l, int r, int rt) {
 74     if(L <= l && r <= R) {
 75         segX[rt].update(yl, yr, 1, n, 1);
 76         return;
 77     }
 78     int mid = (l + r) >> 1;
 79     if(L <= mid) update(yl, yr, L, R, l, mid, lrt);
 80     if(mid < R) update(yl, yr, L, R, mid+1, r, rrt);
 81 }
 82 
 83 int query(int x, int y, int l, int r, int rt) {
 84     int ret = segX[rt].query(y, 1, n, 1);
 85     if(l == r) return ret;
 86     int mid = (l + r) >> 1;
 87     if(x <= mid) ret ^= query(x, y, l, mid, lrt);
 88     else ret ^= query(x, y, mid+1, r, rrt);
 89     return ret;
 90 }
 91 
 92 char op[3];
 93 int xa, ya, xb, yb;
 94 
 95 int main() {
 96     // freopen("in", "r", stdin);
 97     int T;
 98     scanf("%d", &T);
 99     while(T--) {
100         scanf("%d%d",&n,&q);
101         build(1, n, 1);
102         while(q--) {
103             scanf("%s", op);
104             if(op[0] == C) {
105                 scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
106                 update(ya, yb, xa, xb, 1, n, 1);
107             }
108             else {
109                 scanf("%d%d",&xa,&ya);
110                 printf("%d\n", query(xa, ya, 1, n, 1));
111             }
112         }
113         printf("\n");
114     }
115     return 0;
116 }

 

以上是关于[POJ2155] Matrix(二维线段树,树套树)的主要内容,如果未能解决你的问题,请参考以下文章

POJ - 2155 Matrix (二维树状数组 + 区间改动 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)

[POJ 2155]Matrix

POJ poj 2155 Matrix

poj1195 Mobile phones 二维线段树入门

二维线段树之树套树

[poj2155]Matrix(二维树状数组)