[Ybt high-efficiency advanced 4-3-4] matrix maximum value

Maximum value of matrix

Topic link: ybt high-efficiency advanced 4-3-4

General idea

Give you a matrix, ask multiple times, ask the maximum value of a sub-matrix.

Ideas

This question can be seen using a two-dimensional ST table.

It's easy to think of, but the implementation can be said to be very disgusting.

The query is actually okay, the main reason is that the thinking of the merger must be clear.
And because you are a matrix, you have to merge the two cases of one line. (One horizontal line and one vertical line)
Because you are a matrix, if you don't deal with these two, the DP merge will not work normally after it.

You can look at the code for details.

Code

#include<cstdio>
#include<iostream>

using namespace std;

int n, m, k, a[251][251];
int f[251][251][11][11];
int log[251], x1, y1, x2, y2;

void get_log() {
    
    //预处理 log
	int now = 1, x = 0;
	while ((now << 1) <= 250) {
    
    
		for (int i = now; i < (now << 1); i++)
			log[i] = x;
		x++;
		now <<= 1;
	}
	while (now <= 250) {
    
    
		log[now++] = x;
	}
}

int main() {
    
    
	get_log();
	
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
    
    
			scanf("%d", &a[i][j]);
			f[i][j][0][0] = a[i][j];
		}
	
	for (int j = 1; j <= log[m]; j++)//处理横着一根线的
		for (int ii = 1; ii <= n; ii++)
			for (int jj = 1; jj <= m; jj++) {
    
    
				f[ii][jj][0][j] = f[ii][jj][0][j - 1];
				if (jj + (1 << (j - 1)) <= m) f[ii][jj][0][j] = max(f[ii][jj][0][j], f[ii][jj + (1 << (j - 1))][0][j - 1]);
			}
	
	for (int i = 1; i <= log[n]; i++)//处理竖着一根线的
		for (int ii = 1; ii <= n; ii++)
			for (int jj = 1; jj <= m; jj++) {
    
    
				f[ii][jj][i][0] = f[ii][jj][i - 1][0];
				if (ii + (1 << (i - 1)) <= n) f[ii][jj][i][0] = max(f[ii][jj][i][0], f[ii + (1 << (i - 1))][jj][i - 1][0]);
			}
		
	for (int i = 1; i <= log[n]; i++)//ST 表的合并(前面两个其实也是,但是是为了处理掉特殊情况)
		for (int j = 1; j <= log[m]; j++)
			for (int ii = 1; ii <= n; ii++)
				for (int jj = 1; jj <= m; jj++) {
    
    
					f[ii][jj][i][j] = f[ii][jj][i - 1][j - 1];
					if (ii + (1 << (i - 1)) <= n) {
    
    
						f[ii][jj][i][j] = max(f[ii][jj][i][j], f[ii + (1 << (i - 1))][jj][i - 1][j - 1]);
						if (jj + (1 << (j - 1)) <= m) {
    
    
							f[ii][jj][i][j] = max(f[ii][jj][i][j], max(f[ii][jj + (1 << (j - 1))][i - 1][j - 1], f[ii + (1 << (i - 1))][jj + (1 << (j - 1))][i - 1][j - 1]));
						}
					}
					else if (jj + (1 << (j - 1)) <= m) f[ii][jj][i][j] = max(f[ii][jj][i][j], f[ii][jj + (1 << (j - 1))][i - 1][j - 1]);
				}
	
	while (k--) {
    
    
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		int logx = log[x2 - x1 + 1];
		int logy = log[y2 - y1 + 1];//询问
		printf("%d\n", max(max(f[x1][y1][logx][logy], f[x1][y2 - (1 << logy) + 1][logx][logy]), max(f[x2 - (1 << logx) + 1][y1][logx][logy], f[x2 - (1 << logx) + 1][y2 - (1 << logy) + 1][logx][logy])));
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/115048079