滑动窗口
Problem:https://ac.nowcoder.com/acm/problem/50528
题解:
单调队列裸题。
单调队列维护区间最值,对于单调队列有两种操作:
- 插入,新元素从队尾插入后会破坏队列中单调性则删除队尾元素,知道找到插入后不会破坏单调性的位置为止,再将其插入队列。
- 获取最值,读取队首元素。
一般情况下,队列中每个元素保存两个值,下标和状态值。
Code:
/**********************************************************
* @Author: Kirito
* @Date: 2020-07-26 16:29:46
* @Last Modified by: Kirito
* @Last Modified time: 2020-07-26 17:46:42
* @Remark:
**********************************************************/
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll , ll> pll;
const int maxn=1111111;
int arr[maxn],n,k;
deque<pii> box;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
#endif
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>arr[i];
for(int i=0;i<n;i++){
while(!box.empty()&&box.back().second>arr[i])
box.pop_back();
box.push_back(make_pair(i,arr[i]));
while(!box.empty()&&box.front().first<i-k+1)
box.pop_front();
if(i>=k-1)
cout<<box.front().second<<" ";
}
cout<<endl;
while(!box.empty())
box.pop_front();
for(int i=0;i<n;i++){
while(!box.empty()&&box.back().second<arr[i])
box.pop_back();
box.push_back(make_pair(i,arr[i]));
while(!box.empty()&&box.front().first<i-k+1)
box.pop_front();
if(i>=k-1)
cout<<box.front().second<<" ";
}
cout<<endl;
return 0;
}