牛客每日一題3.30 滑動窗口 單調隊列

這道題由於空間限制的很死,所以原本用線段樹之類O(nlogn)的算法都會MLE,唯一的做法就是O(N)的單調隊列。
在這裏插入圖片描述

對於每一個滑動窗口的元素,都是從上一個窗口的基礎上,增加一個新的元素,減掉一個最後的元素。就利用單調雙端隊列去處理問題,對於一個新的窗口就push進去,然後不斷pop直到出現第一個合法的元素,那個元素就是我們要的這個窗口內的最值的答案,不合法的元素是什麼意思呢,就是你這個元素所在的位置太前了, 這個窗口的區間包含不到他,所以只能刪掉。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<time.h>
#include<string>
#include<cmath>
#include<stack>
#include<map>
#include<set>
#define ll long long
#define double long double
using namespace std;
#define PI  3.1415926535898
#define eqs 1e-17
const long long max_ = 1e6 + 7;
int mod = 2014;
const int inf = 1e9 + 7;
const long long INF = 1e18;
int read() {
	int s = 0, f = 1;
	char ch = getchar();
	while (ch<'0' || ch>'9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0'&&ch <= '9') {
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * f;
}
inline void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}
inline int min(int a, int b) {
	return a < b ? a : b;
}
inline int max(int a, int b) {
	return a > b ? a : b;
}
pair<int, int> quemax[max_];
pair<int, int> quemin[max_];
int qmaxL = 1, qmaxR = 0, qminL = 1, qminR = 0;
int n, node[max_],k;
int ansmax[max_], ansmin[max_],an = 0;
signed main() {
	n = read(),k = read();
	for (int i = 1; i <= n; i++) {
		node[i] = read();
	}
	quemax[++qmaxR] = make_pair(node[1], 1);
	quemin[++qminR] = make_pair(node[1], 1);
	for (int i = 2; i <= k; i++) {
		while (qmaxL <= qmaxR && quemax[qmaxR].first < node[i])qmaxR--;
		quemax[++qmaxR] = make_pair(node[i], i);

		while (qminL <= qminR && quemin[qminR].first > node[i])qminR--;
		quemin[++qminR] = make_pair(node[i], i);

	}
	ansmax[++an] = quemax[qmaxL].first, ansmin[an] = quemin[qminL].first;

	for (int i = k + 1; i <= n; i++) {
		//[i - k + 1,i]
		while (qmaxL <= qmaxR && quemax[qmaxR].first < node[i])qmaxR--;
		quemax[++qmaxR] = make_pair(node[i], i);
		while (qmaxL <= qmaxR && quemax[qmaxL].second < i - k + 1)qmaxL++;

		while (qminL <= qminR && quemin[qminR].first > node[i])qminR--;
		quemin[++qminR] = make_pair(node[i], i);
		while (qminL <= qminR && quemin[qminL].second < i - k + 1)qminL++;

		ansmax[++an] = quemax[qmaxL].first, ansmin[an] = quemin[qminL].first;
	}
	for (int i = 1; i <= an; i++) {
		cout << ansmin[i] << " ";
	}
	cout << endl;
	for (int i = 1; i <= an; i++) {
		cout << ansmax[i] << " ";
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章