单调队列30求助 4号关注回报
查看原帖
单调队列30求助 4号关注回报
347589
Zelotz楼主2022/1/26 19:54
#include <bits/stdc++.h>
using namespace std;
#define srand srand(time(NULL))
#define random(x) rand() % (x)
#define il inline
#define ptc putchar
#define reg register
#define mp make_pair
typedef __int128 LL;
typedef long long ll;
typedef pair<int, int> PII;
namespace cyyh {
	template <typename T>
	il void read(T &x) {
		x = 0; T f = 1; char ch;
		while (!isdigit(ch = getchar())) f -= (ch == '-') << 1;
		while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch & 15), ch = getchar(); x *= f;
	}
	template <typename T>
	il void write(T x) {
		if (x < 0) ptc('-'), x = -x;
		if (x > 9) write(x / 10);
		ptc(x % 10 + '0');
	}
	template <typename T>
	il T lowbit(const T &x) {
		return x & -x;
	}
}
using namespace cyyh; 
const int N = 1005;
// f[i][j] / g[i][j]   第i行的滑动窗口最值
// F[i][j] / G[i][j]   第j列的f[i] / g[i]滑动窗口最值 
int n, m, k, a[N][N], f[N][N], g[N][N], F[N][N], G[N][N], ans = INT_MAX;
void work(int i) {
//	cout << endl;
	deque <int> dq, dqq;
	for (int j = 1; j <= m; ++j) {
		if (!dq.empty() && j > k && dq.front() == j - k) dq.pop_front();
		if (!dqq.empty() && j > k && dqq.front() == j - k) dqq.pop_front();
		while (!dq.empty() && a[i][j] > a[i][dq.back()]) dq.pop_back();
		while (!dqq.empty() && a[i][j] < a[i][dqq.back()]) dqq.pop_back();
		dq.push_back(j), dqq.push_back(j);
		if (j >= k) f[i][j] = a[i][dq.front()], g[i][j] = a[i][dqq.front()];
	}
//	for (int j = k; j <= m; ++j) {
//		cout << f[i][j] << ' ';
//	}
//	cout << endl;
}
void work2(int j) {
//	cout << endl;
	deque <int> dq, dqq;
	for (int i = 1; i <= n; ++i) {
		if (!dq.empty() && i > k && dq.front() == i - k) dq.pop_front();
		if (!dqq.empty() && i > k && dqq.front() == i - k) dqq.pop_front();
		while (!dq.empty() && f[i][j] > f[dq.front()][j]) dq.pop_back();
		while (!dqq.empty() && g[i][j] < g[dqq.front()][j]) dqq.pop_back();
		dq.push_back(i), dqq.push_back(i);
		if (i >= k) F[i][j] = f[dq.front()][j], G[i][j] = g[dqq.front()][j];
	}
//	for (int i = k; i <= n; ++i) {
//		cout << F[i][j] << ' ';
//	}
//	cout << endl;
}
int main() {
	cin >> n >> m >> k;
	for (int i = 1; i <= n; ++i) 
		for (int j = 1; j <= m; ++j) 
			cin >> a[i][j];
//	cout << endl;
	for (int i = 1; i <= n; ++i) work(i);
	for (int j = 1; j <= m; ++j) work2(j);
//	cout << endl;
	for (int i = k; i <= n; ++i) {
		for (int j = k; j <= m; ++j) {
//			cout << G[i][j] << ' ';
			ans = min(ans, F[i][j] - G[i][j]);
		}
//		cout << endl;
	}
	cout << ans << endl;
	return 0;
}
2022/1/26 19:54
加载中...