BZOJ 2096 Pilots - 单调队列STL(deque)

传送门

分析:

单调队列:维护两个递增、递减的队列,每次都加入新元素并更新,如果最大值(递减队首)-最小值(递增队首) > k,那么将最左段更新为前面两者中较前的那一个,并弹掉。用deque可以很方便的实现双向的队列。

code

#include<bits/stdc++.h>
using namespace std;
namespace IO {
	template<typename T>
	inline void read(T &x) {
		int i = 0, f = 1; char ch = getchar();
		for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar()); if(ch == '-') ch = getchar(), f = -1;
		for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
		x =  i * f;
	}
	template<typename T>
	inline void wr(T x) {
		if(x < 0) putchar('-'), x = -x; 
		if(x > 9) wr(x / 10);
		putchar(x % 10 + '0');
	}
}using namespace IO;
const int N = 3e6 + 50;
int n, array[N], k, ans;
deque<int> max_que, min_que;
int main() {
	read(k), read(n);
	for(int i = 1; i <= n; i++) read(array[i]);
	int x = 1;
	for(int i = 1; i <= n; i++) {
		while(!max_que.empty() and array[(int)max_que.back()] <= array[i]) max_que.pop_back();
		max_que.push_back(i);
		while(!min_que.empty() and array[(int)min_que.back()] >= array[i]) min_que.pop_back();
		min_que.push_back(i);
		while(!max_que.empty() and !min_que.empty() and array[max_que.front()] - array[min_que.front()] > k)
			(max_que.front() > min_que.front()) ? (x = min_que.front() + 1, min_que.pop_front()) : (x = max_que.front() + 1, max_que.pop_front());
		ans = max(ans, i - x + 1);
	}
	wr(ans);
	return 0;
}
posted @ 2017-11-02 21:19  CzYoL  阅读(384)  评论(0编辑  收藏  举报