二维线段树之矩形树 _求解矩阵和问题
1 //zoj 2859 2 // 二维线段树之矩形树 求解矩阵和问题 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <algorithm> 8 #include <queue> 9 #include <stack> 10 #include <deque> 11 #include <map> 12 #include <iostream> 13 using namespace std; 14 typedef long long LL; 15 const double pi = acos(-1.0); 16 const double e = exp(1); 17 //const int MAXN =2e5+10; 18 //const int N = 200010 * 4; 19 #define INT_MAX (1 << 30) - 1 20 21 const int maxn = 300 * 300 * 1.5; 22 23 struct node { 24 short x1, x2, y1, y2; 25 int min; 26 int ch[4]; 27 }; 28 node tree[maxn]; 29 30 int con[301][301]; 31 int n, tol; 32 33 void build(int x1, int x2, int y1, int y2) 34 { 35 int i; 36 int k = ++tol; 37 tree[k].x1 = x1, tree[k].x2 = x2; 38 tree[k].y1 = y1, tree[k].y2 = y2; 39 tree[k].min = 0; 40 41 if(x1 == x2 && y1 == y2) 42 { 43 tree[k].min = con[x1][y1]; 44 memset(tree[k].ch, 0, sizeof(tree[k].ch)); 45 return ; 46 } 47 48 int midx = (x1 + x2) >> 1; 49 int midy = (y1 + y2) >> 1; 50 51 tree[k].ch[0] = tol + 1; 52 build(x1, midx, y1, midy); //左下 53 54 if(midx + 1 <= x2 && midy + 1 <= y2) //右上 55 { 56 tree[k].ch[1] = tol + 1; 57 build(midx + 1, x2, midy + 1, y2); 58 } 59 else 60 { 61 tree[k].ch[1] = 0; 62 } 63 64 if(midy + 1 <= y2) //左上 65 { 66 tree[k].ch[2] = tol + 1; 67 build(x1, midx, midy + 1, y2); 68 } 69 else 70 { 71 tree[k].ch[2] = 0; 72 } 73 74 75 if(midx + 1 <= x2) //右下 76 { 77 tree[k].ch[3] = tol + 1; 78 build(midx + 1, x2, y1, midy); 79 } 80 else 81 { 82 tree[k].ch[3] = 0; 83 } 84 85 86 tree[k].min = tree[ tree[k].ch[0] ].min; 87 88 for(i = 1; i < 4; i++) 89 { 90 if(tree[k].ch[i]) 91 { 92 tree[k].min = min(tree[k].min, tree[ tree[k].ch[i] ].min); 93 } 94 } 95 96 } 97 98 bool judge(int k, int x1, int x2, int y1, int y2) 99 { 100 if(x1 > tree[k].x2 || x2 < tree[k].x1 || y1 > tree[k].y2 || y2 < tree[k].y1) 101 return false; 102 return true; 103 } 104 105 int Query(int k, int x1, int x2, int y1, int y2) 106 { 107 if(judge(k, x1, x2, y1, y2) == false) 108 return INT_MAX; 109 if(x1 <= tree[k].x1 && x2 >= tree[k].x2 && y1 <= tree[k].y1 && y2 >= tree[k].y2) 110 { 111 return tree[k].min; 112 } 113 114 int minx = Query(tree[k].ch[0], x1, x2, y1, y2); 115 for(int i = 1; i < 4; i++) 116 { 117 minx = min(minx, Query(tree[k].ch[i], x1, x2, y1, y2)); 118 } 119 return minx; 120 } 121 122 123 124 int main() 125 { 126 int i, j, n, size, t; 127 int x1, y1, x2, y2; 128 scanf("%d", &t); 129 while (t--) 130 { 131 //memset(T,0,sizeof(T)); 132 tol = 0; 133 scanf("%d", &size); 134 for (i = 1; i <= size; i++) 135 { 136 for (j = 1; j <= size; j++) 137 { 138 scanf("%d", &con[i][j]); 139 } 140 } 141 build(1, size, 1, size); 142 scanf("%d", &n); 143 while (n--) 144 { 145 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 146 printf("%d\n",Query(1, x1, x2, y1, y2)); 147 } 148 } 149 150 return 0; 151 }