题目:http://poj.org/problem?id=2823
给定一个序列,长度为n,还有一个整数k。
找出所有长度为k的区间求出最大值和最小值,输出。
用单调队列数据结构,我是在这里学习的
在这里学习的http://blog.csdn.net/justmeh/article/details/5844650
单调队列中的元素始终是单调的
例如我们要维护一个单调递增的队列,每次在队尾插入元素的时候,如果之前的元素比它大,就出队,知道知道不大于它,然后进队。我们就是要维护这样的一个队列,
队列中从左向右找到的第一个索引在[i-k+1, i]中的即为答案
ansmin[i]: 以min(a[i], a[i-1], ...,a[i-k+1]);
具体可以看代码。
#include <iostream> #include <cmath> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <set> #include <map> #include <queue> #include <cstdlib> #include <iomanip> using namespace std; #define rep(i, a, b) for( i = (a); i <= (b); i++) #define reps(i, a, b) for( i = (a); i < (b); i++) #define pb push_back #define ps push #define mp make_pair #define CLR(x,t) memset(x,t,sizeof x) #define LEN(X) strlen(X) #define F first #define S second #define Debug(x) cout<<#x<<"="<<x<<endl; const double euler_r = 0.57721566490153286060651209; const double pi = 3.141592653589793238462643383279; const int inf=~0U>>1; const int MOD = int(1e9) + 7; const double EPS=1e-6; typedef long long LL; //poj 2823 //单调队列 //在这里学习的http://blog.csdn.net/justmeh/article/details/5844650 // int n, k, a[1000010], first, last; int q[1000010], ansmax[1000010], ansmin[1000010]; // 单调队列 //ansmin[i]: 以min(a[i], a[i-1], ...,a[i-k+1]); //维护一个单调递增序列,队列中从左向右找到的第一个索引在[i-k+1, i]中的即为答案 void solve1() { int i; CLR(q, 0); last = first = 1;//队列的首尾指针 q[last++] = 1; ansmin[1] = a[1]; rep(i, 2, n) { //找到入队的位置 while(a[q[last - 1]] > a[i] && first < last) last--; q[last++] = i; while(q[first] < i - k + 1 ) first++; ansmin[i] = a[q[first]]; } } //ansmax[i]: 以max(a[i], a[i-1], ...,a[i-k+1]); //维护一个单调递减序列,队列中从左向右找到的第一个索引在[i-k+1, i]中的即为答案 void solve2() { int i; CLR(q, 0); last = first = 1;//队列的首尾指针 q[last++] = 1; ansmax[1] = a[1]; rep(i, 2, n) { //找到入队的位置 while(a[q[last - 1]] < a[i] && first < last) last--; q[last++] = i; while(q[first] < i - k + 1 ) first++; ansmax[i] = a[q[first]]; } } int main() { int i; while(scanf("%d%d",&n,&k) != EOF) { rep(i, 1, n) scanf("%d",&a[i]); solve1(); solve2(); rep(i, k, n) printf("%d ", ansmin[i]); putchar('\n'); rep(i, k, n) printf("%d ", ansmax[i]); putchar('\n'); } return 0; }