所需知识:单调队列
利用双端队列来实现单调队列;
双端队列与普通队列的不同处:双端队列删除元素时既可以删除队头又可以删掉队尾,其可以较好的维护单调队列的单调性;
双端队列的定义及主要函数:
deque<int>q;
q.push_front();//队头插入一个元素
q.push_back();//队尾插入一个元素
q.pop_front();//删除队头元素
q.pop_back();//删除队尾元素
q.front();//返回队头元素
q.back();//返回队尾元素
q.size();//返回队列大小
q.empty();//判断队列是否为空,若为空则返回true,反之,返回false
q.clear();//清空队列
q[i];//返回下标为i的元素
思路:构建一个单调队列,并维护其单调性,即使队列里面的元素严格单调,(若为单调递增,且a[i]<=a[q.back()],则将队尾元素删除,反之若为单调递减,则当a[i]>=a[q.back()]时删除),依次将每个元素下标入队;当队首元素已离开区间时,删除队头,最后在区间长度达到k之后输出每个区间对应的最小值与最大值。
#include <iostream>
#include <cstring>
#include <algorithm>
#include<queue>
const int N=1e6+10;
typedef long long ll;
using namespace std;int n,k;
int a[N];
deque<int>q;
int main()
{cin>>n>>k;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){//i为区间尾的下标//维护队列单调性while(!q.empty()&&a[q.back()]>=a[i]) q.pop_back();//若队头不在区间内则删除if(!q.empty()&&q.front()+k<=i) q.pop_front();q.push_back(i);//当区间长度大于k时才输出if(i>=k) cout<<a[q.front()]<<' ';} cout<<endl;//清空队列q.clear();for(int i=1;i<=n;i++){//维护队列单调性while(!q.empty()&&a[q.back()]<=a[i]) q.pop_back();//若队头不在区间内则删除if(!q.empty()&&q.front()+k<=i) q.pop_front();q.push_back(i);//当区间长度大于k时才输出if(i>=k) cout<<a[q.front()]<<' ';}return 0;
}