http://poj.org/problem?id=2823
给你一个序列a,要找到两个序列 a的下标为i,i+1,i+2, ….. i+k-1 当中的最小值为b[i]; c[i]就是最大值
单调队列,紫书中第八章的滑动窗口。。
优先队列也可做
优先队列的写法
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; typedef long long ll; #define MS(a) memset(a,0,sizeof(a)) #define MP make_pair #define PB push_back const int INF = 0x3f3f3f3f; const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ////////////////////////////////////////////////////////////////////////// const int maxn = 1e6+10; int a[maxn],mi[maxn],mx[maxn]; struct node1{ int i; bool operator<(const node1& rhs) const{ return a[i]>a[rhs.i]; } }; struct node2{ int i; bool operator<(const node2& rhs) const{ return a[i]<a[rhs.i]; } }; priority_queue<node1> q1; priority_queue<node2> q2; int main(){ int n,k; scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) a[i] = read(); for(int i=1; i<k; i++){ q1.push(node1{i}); q2.push(node2{i}); } int cnt1=0,cnt2=0; for(int i=k; i<=n; i++){ q1.push(node1{i}); q2.push(node2{i}); while(i-q1.top().i >= k) q1.pop(); mi[cnt1++] = a[q1.top().i]; while(i-q2.top().i >= k) q2.pop(); mx[cnt2++] = a[q2.top().i]; } for(int i=0; i<cnt1; i++){ cout << mi[i]; if(i==cnt1-1) cout << endl; else cout << " "; } for(int i=0; i<cnt2; i++){ cout << mx[i]; if(i==cnt2-1) cout << endl; else cout << " "; } return 0; }