20分单调队列
查看原帖
20分单调队列
1063896
Mickey_miqi楼主2024/10/4 09:45
#include<bits/stdc++.h>
using namespace std;
#define A 1005
#define N 105
int a, b, n;
long long ans = 0x3f3f3f3f3f3f3f3f, c[A][A], q[N], d[A][A], f[A][A], e[A][A], g[A][A];
int main() {
	scanf("%d%d%d", &a, &b, &n);
	for (int i = 1; i <= a; i++) {
		for (int j = 1; j <= b; j++) {
			scanf("%lld", &c[i][j]);
		}
	}
	for (int i = 1; i <= a; i++) {
		int h = 1, t = 0;
		memset(q, 0, sizeof(q));
		for (int j = 1; j <= b; j++) {
			while (h <= t && c[i][q[t]] < c[i][j]) {
				t--;
			}
			q[++t] = j;
			if (q[h]+n-1<j) h++;
			d[i][j] = max(d[i][j], c[i][q[h]]);
		}
	}
	for (int j = n; j <= b; j++) {
		for (int i = n; i <= a; i++) {
			for (int k = i-n+1; k <= a; k++) {
				f[i][j] = max(f[i][j], d[k][j]);
			}
		}
	}
	memset(e, 0x3f, sizeof(e));
	memset(g, 0x3f, sizeof(g));
	for (int i = 1; i <= a; i++) {
		int h = 1, t = 0;
		memset(q, 0, sizeof(q));
		for (int j = 1; j <= b; j++) {
			while (h <= t && c[i][q[t]] > c[i][j]) {
				t--;
			}
			q[++t] = j;
			if (q[h]+n-1<j) h++;
			e[i][j] = min(e[i][j], c[i][q[h]]);
		}
	}
	for (int j = n; j <= b; j++) {
		for (int i = n; i <= a; i++) {
			for (int k = i-n+1; k <= a; k++) {
				g[i][j] = min(g[i][j], e[k][j]);
			}
		}
	}
	for (int i = n; i <= a; i++) {
		for (int j = n; j <= b; j++) {
			ans = min(ans, f[i][j]-g[i][j]);
		}
	}
	printf("%lld", ans);
	return 0;
}


2024/10/4 09:45
加载中...