开始我用线段树做的,,,后来看题解才发现也可以用双调队列做而且更直观
单调队列就是维护一个典调递增或递减的队列,在这个题目里主要就是利用单调队列尽量保留有效信息舍弃无效信息,所以1求最小值时要用单调递增队列,最大值要用递减序列。这样即抛弃了无效值,又能保证有效值能一直维持到最后发挥作用。学习了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<deque>
#include<algorithm>
#define MAX 1001000
using namespace std;
long long n,m,s[MAX];
struct nod{
long long index,value;
nod(long long i,long long v){index=i,value=v;}
};
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>s[i];
}
deque<nod>a;
int i;
for(i=0;i<m;i++){
while(!a.empty()&&s[i]<a.back().value)
a.pop_back();
if(a.empty()||(!a.empty()&&s[i]>a.back().value))
a.push_back(nod(i,s[i]));
}
cout<<a.front().value;
for(;i<n;i++){
while(!a.empty()&&a.front().index<=i-m)
a.pop_front();
while(!a.empty()&&s[i]<a.back().value)
a.pop_back();
if(a.empty()||(!a.empty()&&s[i]>a.back().value))
a.push_back(nod(i,s[i]));
cout<<" "<<a.front().value;
}
cout<<endl;
deque<nod>b;
for(i=0;i<m;i++){
while(!b.empty()&&s[i]>b.back().value)
b.pop_back();
if(b.empty()||(!b.empty()&&s[i]<b.back().value))
b.push_back(nod(i,s[i]));
}
cout<<b.front().value;
for(;i<n;i++){
while(!b.empty()&&b.front().index<=i-m)
b.pop_front();
while(!b.empty()&&s[i]>b.back().value)
b.pop_back();
if(b.empty()||(!b.empty()&&s[i]<b.back().value))
b.push_back(nod(i,s[i]));
cout<<" "<<b.front().value;
}
cout<<endl;
return 0;
}