二维RMQ, 注意从一维到二维的过程。
Accepted | 2859 | C++ | 00:02.25 | 29064K |
#include<stdio.h>
#define min(x, y) ((x) < (y) ? (x) : (y))
int f[301][301][9][9 ];
void setmin(int x, int y, int width, int height)
{
int width1 = width == 0 ? 0 : width - 1 ;
int height1 = height == 0 ? 0 : height - 1 ;
int x1 = x + (1 << width1), y1 = y + (1 << height1);
if(width == 0 )
f[x][y][width][height] = min(f[x][y][width1][height1], f[x][y1][width1][height1]);
else if(height == 0 )
f[x][y][width][height] = min(f[x][y][width1][height1], f[x1][y][width1][height1]);
else f[x][y][width][height] = min(f[x][y][width1][height], f[x1][y][width1][height]);
}
int search()
{
int r1, c1, r2, c2;
scanf("%d%d%d%d", &r1, &c1, &r2, & c2);
--r1, --c1, --r2, -- c2;
int width = c2 - c1 + 1, height = r2 - r1 + 1 ;
int w = 1, h = 1 ;
int cw = 0, ch = 0 ;
while((width & ~(w - 1)) != 0 )
w <<= 1, cw++ ;
while((height & ~(h - 1)) != 0 )
h <<= 1, ch++ ;
cw--, ch-- ;
w = (w >> 1) - 1, h = (h >> 1) - 1 ;
return min(min(f[c1][r1][cw][ch], f[c2 - w][r1][cw][ch]),
min(f[c1][r2 - h][cw][ch], f[c2 - w][r2 - h][cw][ch]));
}
void solve(int n)
{
for(int i = 0; i < n; i++ )
for(int j = 0; j < n; j++ )
scanf("%d", &f[j][i][0][0 ]);
for(int width = 0; (1 << width) <= n; width++ )
for(int i = 0; i + (1 << width) <= n; i++ )
for(int height = 0; (1 << height) <= n; height++ )
for(int j = 0; j + (1 << height) <= n; j++ )
if(width == 0 && height == 0) break ;
else setmin(i, j, width, height);
int m;
scanf("%d", & m);
while(m--) printf("%d/n" , search());
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("2859.txt", "r" , stdin);
#endif
int t, n;
while(scanf("%d", &t) != EOF)
while(t-- && scanf("%d", &n) != EOF)
solve(n);
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
return 0 ;
}
#define min(x, y) ((x) < (y) ? (x) : (y))
int f[301][301][9][9 ];
void setmin(int x, int y, int width, int height)
{
int width1 = width == 0 ? 0 : width - 1 ;
int height1 = height == 0 ? 0 : height - 1 ;
int x1 = x + (1 << width1), y1 = y + (1 << height1);
if(width == 0 )
f[x][y][width][height] = min(f[x][y][width1][height1], f[x][y1][width1][height1]);
else if(height == 0 )
f[x][y][width][height] = min(f[x][y][width1][height1], f[x1][y][width1][height1]);
else f[x][y][width][height] = min(f[x][y][width1][height], f[x1][y][width1][height]);
}
int search()
{
int r1, c1, r2, c2;
scanf("%d%d%d%d", &r1, &c1, &r2, & c2);
--r1, --c1, --r2, -- c2;
int width = c2 - c1 + 1, height = r2 - r1 + 1 ;
int w = 1, h = 1 ;
int cw = 0, ch = 0 ;
while((width & ~(w - 1)) != 0 )
w <<= 1, cw++ ;
while((height & ~(h - 1)) != 0 )
h <<= 1, ch++ ;
cw--, ch-- ;
w = (w >> 1) - 1, h = (h >> 1) - 1 ;
return min(min(f[c1][r1][cw][ch], f[c2 - w][r1][cw][ch]),
min(f[c1][r2 - h][cw][ch], f[c2 - w][r2 - h][cw][ch]));
}
void solve(int n)
{
for(int i = 0; i < n; i++ )
for(int j = 0; j < n; j++ )
scanf("%d", &f[j][i][0][0 ]);
for(int width = 0; (1 << width) <= n; width++ )
for(int i = 0; i + (1 << width) <= n; i++ )
for(int height = 0; (1 << height) <= n; height++ )
for(int j = 0; j + (1 << height) <= n; j++ )
if(width == 0 && height == 0) break ;
else setmin(i, j, width, height);
int m;
scanf("%d", & m);
while(m--) printf("%d/n" , search());
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("2859.txt", "r" , stdin);
#endif
int t, n;
while(scanf("%d", &t) != EOF)
while(t-- && scanf("%d", &n) != EOF)
solve(n);
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
return 0 ;
}