[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 (二维树状数组 + 区间改动 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)