1.预处理时间复杂度O(n*m*log(m),查询时间复杂度O(n)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 305
using namespace std;
typedef long long ll;
int d[300][300][10];
int n, m;
void ST(){
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &d[i][j][0]);
for(int i = 0; i < n; i++)
for(int j = 1; (1<<j) <= m; j++)
for(int h = 0; h + (1<<j) <= m; h++)
d[i][h][j] = max(d[i][h][j-1], d[i][h+(1<<(j-1))][j-1]);
}
int Query(int r1, int c1, int r2, int c2){
int k = 0;
while(1<<(k+1) <= c2-c1+1)
k++;
int maxs = 0;
for(int i = r1; i <= r2; i++)
maxs = max(maxs, max(d[i][c1][k], d[i][c2-(1<<k)+1][k]));
return maxs;
}
int main(){
// freopen("in.txt", "r", stdin);
while(scanf("%d%d", &n, &m) == 2){
ST();
int q, r1, c1, r2, c2;
scanf("%d", &q);
while(q--){
scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
r1--, c1--, r2--, c2--;
int p = Query(r1, c1, r2, c2);
printf("%d ", p);
if(p == d[r1][c1][0] || p == d[r1][c2][0]
|| p == d[r2][c1][0] || p == d[r2][c2][0])
puts("yes");
else
puts("no");
}
}
return 0;
}
2.预处理时间复杂度O(n*m*log(n)*log(m), 查询时间复杂度O(1)
这道题开了个d[301][301][9][9],四维数组,其中第3维和第4维开到10就MLE了,改成9就过了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 305
using namespace std;
typedef long long ll;
int d[301][301][9][9];
int n, m;
void ST(){
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &d[i][j][0][0]);
for(int i = 0; (1<<i) <= n; i++)
for(int j = 0; (1<<j) <= m; j++)
for(int k1 = 0; k1+(1<<i) <= n; k1++)
for(int k2 = 0; k2+(1<<j) <= m; k2++){
if(i == 0 && j == 0)
continue;
if(i == 0)
d[k1][k2][i][j] = max(d[k1][k2][i][j-1], d[k1][k2+(1<<(j-1))][i][j-1]);
else if(j == 0)
d[k1][k2][i][j] = max(d[k1][k2][i-1][j], d[k1+(1<<(i-1))][k2][i-1][j]);
else{
d[k1][k2][i][j] = max(max(d[k1][k2][i-1][j-1], d[k1+(1<<(i-1))][k2][i-1][j-1]),
max(d[k1][k2+(1<<(j-1))][i-1][j-1], d[k1+(1<<(i-1))][k2+(1<<(j-1))][i-1][j-1]));
}
}
}
int Query(int r1, int c1, int r2, int c2){
int k1 = 0, k2 = 0;
while(1<<(k1+1) <= r2-r1+1)
k1++;
while(1<<(k2+1) <= c2-c1+1)
k2++;
return max(max(d[r1][c1][k1][k2], d[r2-(1<<k1)+1][c1][k1][k2]),
max(d[r1][c2-(1<<k2)+1][k1][k2], d[r2-(1<<k1)+1][c2-(1<<k2)+1][k1][k2]));
}
int main(){
//freopen("in.txt", "r", stdin);
while(scanf("%d%d", &n, &m) == 2){
int q, r1, c1, r2, c2;
ST();
scanf("%d", &q);
while(q--){
scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
r1--, c1--, r2--, c2--;
int p = Query(r1, c1, r2, c2);
printf("%d ", p);
if(p == d[r1][c1][0][0] || p == d[r1][c2][0][0]
|| p == d[r2][c1][0][0] || p == d[r2][c2][0][0])
puts("yes");
else
puts("no");
}
}
return 0;
}