题目描述
一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。
输入输出格式
输入格式:
第一行两个数n,m。
第二行,n个正整数,为所给定的数列。
输出格式:
n行,第i行的一个数ai,为所求序列中第i个数前m个数的最小值。
输入样例#1:
6 2
7 8 1 4 3 2
输出样例#1:
0
7
7
1
1
3
说明
【数据规模】
m≤n≤2000000,ai ≤3×10 ^7
单调队列
#include<bits/stdc++.h>
using namespace std;
char buf[1<<17],*L=buf,*R=buf;
#define gc() L==R&&(R=(L=buf)+fread(buf,1,1<<17,stdin),L==R)?EOF:*L++;
template<typename T>
inline void read(T&x) {
int flag=x=0;
char ch=gc();
while (ch<'0'||ch>'9')
flag|=ch=='-',ch=gc();
while (ch>='0'&&ch<='9')
x=(x<<3)+(x<<1)+ch-48,ch=gc();
if(flag)
x=-x;
}
const int MAXN=1e5+10;
int n,m,ans[MAXN];
struct Node{
int num,val;
}x;
deque<Node>que;
int main() {
freopen("in.txt","r",stdin);
read(n),read(m);
for(int i=1;i<n;++i){
read(x.val);
x.num=i;
//当前val就是该区间最后一个数,如果他前面的都比他大,都弹出
while(!que.empty()&&que.back().val>x.val)que.pop_back();
que.push_back(x);//压入
//从队头弹出不在区间里的数
while(!que.empty()&&que.front().num<=i-m)que.pop_front();
ans[i]=que.front().val;
}
for(int i=0;i<n;++i){
printf("%d\n",ans[i]);
}
return 0;
}