TOJ 1588 Cornfields -- 二維RMQ

題目鏈接:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1588

分析:二維RMQ,和一維的區別不大,詢問的時候把一個大的矩形劃分成4個小矩形。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define mp make_pair
#define X first
#define Y second
#define MEMSET(a, b) memset(a, b, sizeof(a))
using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair pii;
typedef vector vi;
typedef vi::iterator vi_it;
typedef map mii;
typedef priority_queue pqi;
typedef priority_queue, greater > rpqi;
typedef priority_queue pqp;
typedef priority_queue, greater > rpqp;

const int MAX_N = 250 + 2;
int dp[MAX_N][MAX_N][8][8][2];

void make_rmq(int n)
{
	int r, c, i, j;
	for (i = 0; (1 << i) <= n; ++i) {
		for (j = 0; (1 << j) <= n; ++j) {
			if (!i && !j) {
				continue;
			}
			for (r = 1; r + (1 << i) - 1 <= n; ++r) {
				for (c = 1; c + (1 << j) - 1 <= n; ++c) {
					if (i == 0) {
						dp[r][c][i][j][0] = min(dp[r][c][i][j - 1][0],
							dp[r][c + (1 << (j - 1))][i][j - 1][0]);
						dp[r][c][i][j][1] = max(dp[r][c][i][j - 1][1],
							dp[r][c + (1 << (j - 1))][i][j - 1][1]);
					}
					else {
						dp[r][c][i][j][0] = min(dp[r][c][i - 1][j][0],
							dp[r + (1 << (i - 1))][c][i - 1][j][0]);
						dp[r][c][i][j][1] = max(dp[r][c][i - 1][j][1],
							dp[r + (1 << (i - 1))][c][i - 1][j][1]);
					}
				}
			}
		}
	}
}

int query(int r1, int c1, int r2, int c2)
{
	int k1 = (int)(log((double)(r2 - r1 + 1)) / log(2.0));
	int k2 = (int)(log((double)(c2 - c1 + 1)) / log(2.0));
	int minv = min(min(dp[r1][c1][k1][k2][0], dp[r1][c2 - (1 << k2) + 1][k1][k2][0]),
		min(dp[r2 - (1 << k1) + 1][c1][k1][k2][0],
		dp[r2 - (1 << k1) + 1][c2 - (1 << k2) + 1][k1][k2][0]));
	int maxv = max(max(dp[r1][c1][k1][k2][1], dp[r1][c2 - (1 << k2) + 1][k1][k2][1]),
		max(dp[r2 - (1 << k1) + 1][c1][k1][k2][1],
		dp[r2 - (1 << k1) + 1][c2 - (1 << k2) + 1][k1][k2][1]));
	return maxv - minv;
}

int main(int argc, char *argv[])
{
//	freopen("D:\\in.txt", "r", stdin);
	int n, b, k, i, j;
	cin >> n >> b >> k;
	for (i = 1; i <= n; ++i) {
		for (j = 1; j <= n; ++j) {
			cin >> dp[i][j][0][0][0];
			dp[i][j][0][0][1] = dp[i][j][0][0][0];
		}
	}
	make_rmq(n);
	while (k--) {
		int x, y;
		cin >> x >> y;
		cout << query(x, y, x + b - 1, y + b - 1) << endl;
	}
	return 0;
}

發佈了49 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章