ybtoj RMQ问题课堂过关例题4矩阵最值

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ybtoj RMQ问题课堂过关例题4矩阵最值相关的知识,希望对你有一定的参考价值。

【例题4】矩阵最值


Link

传送门
题面//因为不知道侵不侵权所以就是题面是私密的,有账号的直接看转送门就可了


题目大意


解题思路

设 f[x][y][i][j] 代表 左上角(x, y),右下角(x + 2 i 2^i 2i, y + 2 j 2^j 2j) 的矩阵的答案
(具体操作看程序)
tips1: 记得先把一条横和一条竖的处理出来(就有点像初始化吧,毕竟是矩阵)
tips2: 注意一下循环层的顺序,自行理解一下


Code

#include <iostream>
#include <cstdio>

using namespace std;

int n, m, k, lg[260], f[260][260][20][20], ans;

void Log() {
	int now = 1, root = 0;
	while((now << 1) <= 250) {
		for(int i = now; i < (now << 1); i++)
				lg[i] = root;
		root++;
		now <<= 1;
	}
	while(now <= 250)
		lg[now++] = root;
}

int main() {
	scanf("%d %d %d", &n, &m, &k);
	Log();   //求lg
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			scanf("%d", &f[i][j][0][0]);  //初始化
	for(int j = 1; j <= lg[m]; j++)  //处理一条横的
		for(int x = 1; x <= n; x++)
			for(int y = 1; y <= m; y++) {
				f[x][y][0][j] = f[x][y][0][j - 1];
				if(y + (1 << (j - 1)) <= m)
					f[x][y][0][j] = max(f[x][y][0][j],
					 f[x][y + (1 << (j - 1))][0][j - 1]);
			}
	for(int i = 1; i <= lg[n]; i++)  //处理一条竖的
		for(int x = 1; x <= n; x++)
			for(int y = 1; y <= m; y++) {
				f[x][y][i][0] = f[x][y][i - 1][0];
				if(x + (1 << (i - 1)) <= n)
					f[x][y][i][0] = max(f[x][y][i][0],
					 f[x + (1 << (i - 1))][y][i - 1][0]);
			}
	for(int i = 1; i <= lg[n]; i++)
		for(int j = 1; j <= lg[m]; j++)
			for(int x = 1; x <= n; x++)
				for(int y = 1; y <= m; y++) {
					f[x][y][i][j] = f[x][y][i - 1][j - 1];
					if(x + (1 << (i - 1)) <= n) {  //以下把所有max都得取清楚了
						f[x][y][i][j] = max(f[x][y][i][j],
						 f[x + (1 << (i - 1))][y][i - 1][j - 1]);
						if(y + (1 << (j - 1)) <= m)
							f[x][y][i][j] = max(f[x][y][i][j], max(f[x][y + (1 << (j - 1))][i - 1][j - 1], f[x + (1 << (i - 1))][y + (1 << (j - 1))][i - 1][j - 1])
							 );		
					} else {
						if(y + (1 << (j - 1)) <= m)
							f[x][y][i][j] = max(f[x][y][i][j],
							 f[x][y + (1 << (j - 1))][i - 1][j - 1]);
					}
				}
	while(k--) {
		int x, y, xx, yy;
		scanf("%d %d %d %d", &x, &y, &xx, &yy);
		int i = lg[xx - x + 1], j = lg[yy - y + 1];
		ans = f[x][y][i][j];  //又是一大堆取max
		ans = max(ans, f[x][yy - (1 << j) + 1][i][j]);
		ans = max(ans, f[xx - (1 << i) + 1][y][i][j]);
		ans = max(ans, f[xx - (1 << i) + 1][yy - (1 << j) + 1][i][j]);
		printf("%d\\n", ans);
	} 
}

以上是关于ybtoj RMQ问题课堂过关例题4矩阵最值的主要内容,如果未能解决你的问题,请参考以下文章

luogu P4514ybtoj树状数组课堂过关差分 例题6区间修改区间查询 & 上帝造题的七分钟

ybtoj背包问题课堂过关DP例题3宝物筛选

ybtoj 倍增问题课堂过关例题1查找编号

ybtoj线段树课堂过关例题1求区间和

Ybtoj 树形DP课堂过关例题3最长距离

luogu P4513ybtoj线段树课堂过关例题3小白逛公园