单调队列
单调队列:是指队列中存在递增/递减。
这个在求Sliding Window的时候特别好用。
比如。需要求这一区间的最小值。
则只需维持一个递增队列,当存在比队列中更小的数字时,将队列中所有比这个数大的都pop出去。
如果用stl中的list来的话,不能使用二分法。来快速pop出。
所以还是使用数组来模拟队列,即快又简单。
附poj 2823 ac代码
#include <iostream>
#include <cassert>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <climits>
#include <functional>
#include <list>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <algorithm>
#define ll long long
using namespace std;
#define MAXN 1000010
int minList[MAXN];
int minh,mint;
int maxList[MAXN];
int maxh,maxt;
int alldata[MAXN];
int minFront(){
return minList[minh];
}
int maxFront(){
return maxList[maxh];
}
void minPopFornt(){
minh++;
}
void maxPopFornt(){
maxh++;
}
void minPushBack(int v){
int l = minh;
int r = mint-1;
while(l<=r){
int mid = (l+r)>> 1;
if ( minList[mid] <= v ){
l = mid+1;
}else{
r = mid-1;
}
}
mint = l;
minList[mint++] = v;
}
void maxPushBack(int v){
int l = maxh;
int r = maxt-1;
while(l<=r){
int mid = (l+r)>> 1;
if ( maxList[mid] >= v ){
l = mid+1;
}else{
r = mid-1;
}
}
maxt = l;
maxList[maxt++] = v;
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
k %= n;
int v;
if ( k == 1 ){
vector<int> vec(n);
for( int i=0;i<n;++i ){
scanf("%d",&v);
vec[i] = v;
}
for( int i=0;i<n;++i ){
printf("%d ",vec[i]);
}
printf("\n");
for( int i=0;i<n;++i ){
printf("%d ",vec[i]);
}
printf("\n");
return 0;
}
if ( k == 0 ){
int mi = INT_MAX;
int ma = INT_MIN;
for( int i=0;i<n;++i ){
scanf("%d",&v);
mi = min(mi,v);
ma = max(ma,v);
}
printf("%d\n%d\n",mi,ma);
return 0;
}
//vector<int> minVec(n-k+1);
//vector<int> maxVec(n-k+1);
for( int i=0;i<n;++i ){
scanf("%d",&v);
alldata[i] = v;
}
int datah=0;
int datat=k;
for( int i=0;i<k;++i ){
v = alldata[i];
minPushBack(v);
maxPushBack(v);
}
datah=0;
datat = k;
for( int i=k;i<n;++i ){
printf("%d ",minFront());
if ( alldata[datah] == minFront() ){
minPopFornt();
}
datah++;
minPushBack(alldata[i]);
datat++;
}
printf("%d\n",minFront());
datah=0;
datat = k;
for( int i=k;i<n;++i ){
printf("%d ",maxFront());
if ( alldata[datah] == maxFront() ){
maxPopFornt();
}
datah++;
maxPushBack(alldata[i]);
datat++;
}
printf("%d\n",maxFront());
return 0;
}