Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 5310 | Accepted: 2613 |
Description
FJ has, at great expense, surveyed his square farm of N x N hectares (1 <= N <= 250). Each hectare has an integer elevation (0 <= elevation <= 250) associated with it.
FJ will present your program with the elevations and a set of K (1 <= K <= 100,000) queries of the form "in this B x B submatrix, what is the maximum and minimum elevation?". The integer B (1 <= B <= N) is the size of one edge of the square cornfield and is a constant for every inquiry. Help FJ find the best place to put his cornfield.
Input
* Lines 2..N+1: Each line contains N space-separated integers. Line 2 represents row 1; line 3 represents row 2, etc. The first integer on each line represents column 1; the second integer represents column 2; etc.
* Lines N+2..N+K+1: Each line contains two space-separated integers representing a query. The first integer is the top row of the query; the second integer is the left column of the query. The integers are in the range 1..N-B+1.
Output
Sample Input
5 3 1 5 1 2 6 3 1 3 5 2 7 7 2 4 6 1 9 9 8 6 5 0 6 9 3 9 1 2
Sample Output
5
題意:給出一個矩陣,k個詢問,每個詢問a b,輸出以第a行第b列元素爲左上角的大小爲B*B的子矩陣中最大值與最小值之差。
思路:裸的二維RMQ
AC代碼:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#define ll long long
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
using namespace std;
const int INF = 1e9;
const int maxn = 250;
int a[maxn][maxn];
int pmax[maxn][maxn][15], pmin[maxn][maxn][15];
int n, d, q;
void init_rmq()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
pmax[i][j][0] = pmin[i][j][0] = a[i][j];
for(int i = 1; i <= n; i++)
for(int k = 1; (1 << k) <= n; k++)
for(int j = 1; j + (1 << k) - 1 <= n; j++)
{
pmax[i][j][k] = max(pmax[i][j][k - 1], pmax[i][j + (1 << (k - 1))][k - 1]);
pmin[i][j][k] = min(pmin[i][j][k - 1], pmin[i][j + (1 << (k - 1))][k - 1]);
}
}
int RMQ(int a,int b)
{
int k = (int)(log(double(d)) / log(2.0));
int maxans = 0, minans = INF;
int l = b, r = b + d - 1;
for(int i = a; i < a + d; i++)
{
maxans = max(maxans, max(pmax[i][l][k], pmax[i][r - (1 << k) + 1][k]));
minans = min(minans, min(pmin[i][l][k], pmin[i][r - (1 << k) + 1][k]));
}
return maxans - minans;
}
int main()
{
int x, y;
while(~scanf("%d%d%d", &n, &d, &q))
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
init_rmq();
while(q--)
{
scanf("%d%d", &x, &y);
printf("%d\n", RMQ(x, y));
}
}
return 0;
}