#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int stmin[301][301][9][9];
int n;//n行n列
int q;
void init_st(int n)
{
int i, j, k1, k2;
for(k1 = 0; k1 <= (int)log2(n); ++k1)
for(k2 = 0; k2 <= (int)log2(n); ++k2)
{
if(!k1 && !k2) continue;
for(i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
{
int tag1 = i + (1<<k1) - 1;
int tag2 = j + (1<<k2) - 1;
if(tag1 > n || tag2 > n) continue;
if(!k1) stmin[i][j][0][k2] = min(stmin[i][j][0][k2-1], stmin[i][j+(1<<(k2-1))][0][k2-1]);
else stmin[i][j][k1][k2] = min(stmin[i][j][k1-1][k2], stmin[i+(1<<(k1-1))][j][k1-1][k2]);
}
}
}
int query(int x1, int y1, int x2, int y2)
{
int k1 = log2(x2-x1+1);
int k2 = log2(y2-y1+1);
int t1 = min(stmin[x1][y1][k1][k2], stmin[x2-(1<<k1)+1][y2-(1<<k2)+1][k1][k2]);
int t2 = min(stmin[x1][y2-(1<<k2)+1][k1][k2], stmin[x2-(1<<k1)+1][y1][k1][k2]);
int ret = min(t1, t2);
return ret;
}
int main()
{
int i, j, x1, y1, x2, y2;
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
scanf("%d", &stmin[i][j][0][0]);
init_st(n);
scanf("%d", &q);
while(q--)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
int ans = query(x1, y1, x2, y2);
printf("%d\n", ans);
}
}
return 0;
}
降成三维储存
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n, q;
int st[301][301][10];
void init_st(int n)
{
int i, j, k;
for(k = 1; k <= (int)log2(n); ++k)
for(i = 1; i <= n-(1<<k)+1; ++i)
for(j = 1; j <= n-(1<<k)+1; ++j)
{
int t1 = min(st[i][j][k-1], st[i+(1<<(k-1))][j][k-1]);
int t2 = min(st[i][j+(1<<(k-1))][k-1], st[i+(1<<(k-1))][j+(1<<(k-1))][k-1]);
st[i][j][k] = min(t1, t2);
}
}
int query(int x1, int y1, int x2, int y2)
{
int k1 = log2(x2-x1+1);
int k2 = log2(y2-y1+1);
if(k1==k2) return min(st[x1][y1][k1], min(st[x2-(1<<k1)+1][y1][k1], min(st[x1][y2-(1<<k2)+1][k1], st[x2-(1<<k1)+1][y2-(1<<k2)+1][k1])));
if(k1<k2)
{
int k = k1;
int minret = 0x3f3f3f3f;
for(int i = y1; i <= y2 - (1<<k) + 1; i += (1<<k))
minret = min(minret, min(st[x1][i][k], st[x2-(1<<k)+1][i][k]));
minret = min(minret, min(st[x1][y2-(1<<k)+1][k], st[x2-(1<<k)+1][y2-(1<<k)+1][k]));
return minret;
}
int k = k2;
int minret = 0x3f3f3f3f;
for(int i = x1; i <= x2-(1<<k)+1; i += (1<<k))
minret = min(minret, min(st[i][y1][k], st[i][y2-(1<<k)+1][k]));
minret = min(minret, min(st[x2-(1<<k)+1][y1][k], st[x2-(1<<k)+1][y2-(1<<k)+1][k]));
return minret;
}
int main()
{
int i, j, t, q, x1, x2, y1, y2;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
scanf("%d", &st[i][j][0]);
init_st(n);
scanf("%d", &q);
while(q--)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
int ans = query(x1, y1, x2, y2);
printf("%d\n", ans);
}
}
return 0;
}