【HDOJ】2888 Check Corners
二维RMQ。
1 /* 2888 */ 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 using namespace std; 8 9 #define MAXN 305 10 #define MAXM 9 11 12 int bit[MAXN]; 13 int dp[MAXN][MAXN][MAXM][MAXM]; 14 int n, m; 15 16 void RMQ_init() { 17 int i, j, k; 18 int ii, jj; 19 20 for (i=1; i<=n; ++i) 21 for (j=1; j<=m; ++j) 22 scanf("%d", &dp[i][j][0][0]); 23 for (ii=0; (1<<ii)<=n; ++ii) { 24 for (jj=0; (1<<jj)<=m; ++jj) { 25 if (ii==0 && jj==0) 26 continue; 27 for (i=1; i+(1<<ii)-1<=n; ++i) { 28 for (j=1; j+(1<<jj)-1<=m; ++j) { 29 if (ii) 30 dp[i][j][ii][jj] = max(dp[i][j][ii-1][jj], dp[i+(1<<(ii-1))][j][ii-1][jj]); 31 else 32 dp[i][j][ii][jj] = max(dp[i][j][ii][jj-1], dp[i][j+(1<<(jj-1))][ii][jj-1]); 33 } 34 } 35 } 36 } 37 } 38 39 int RMQ(int lx, int ly, int rx, int ry) { 40 int kx = 0, ky = 0; 41 42 while ((1<<(kx+1)) <= (rx-lx+1)) 43 ++kx; 44 while ((1<<(ky+1)) <= (ry-ly+1)) 45 ++ky; 46 return max( 47 max(dp[lx][ly][kx][ky], dp[rx-(1<<kx)+1][ly][kx][ky]), 48 max(dp[lx][ry-(1<<ky)+1][kx][ky], dp[rx-(1<<kx)+1][ry-(1<<ky)+1][kx][ky]) 49 ); 50 } 51 52 int main() { 53 int i, j, k; 54 int r1, c1, r2, c2; 55 56 #ifndef ONLINE_JUDGE 57 freopen("data.in", "r", stdin); 58 freopen("data.out", "w", stdout); 59 #endif 60 61 while (scanf("%d %d", &n, &m)!=EOF) { 62 RMQ_init(); 63 scanf("%d", &j); 64 while (j--) { 65 scanf("%d %d %d %d", &r1, &c1, &r2, &c2); 66 if (r1 > r2) swap(r1, r2); 67 if (c1 > c2) swap(c1, c2); 68 k = RMQ(r1, c1, r2, c2); 69 if (k==dp[r1][c1][0][0] || k==dp[r1][c2][0][0] || k==dp[r2][c1][0][0] || k==dp[r2][c2][0][0]) 70 printf("%d yes\n", k); 71 else 72 printf("%d no\n", k); 73 } 74 } 75 76 return 0; 77 }