题目描述
一个含有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
一看到题目,以为是 RMQ问题,打了一发 ST表 ,结果 TLE 了两个点。。。
再一看数据,200W。。。
后来才想到了单调队列。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAX 999999999
#define MAXN 2000010
using namespace std;
int n,m,l=1,r=0,ans=MAX,a[MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
a[i]=read();
if(ans==MAX)printf("0\n");
else printf("%d\n",ans);
if(a[i]<ans)ans=a[i];
else if(r-l+1>=m&&ans==a[l]){
ans=MAX;
for(int j=l+1;j<=r+1;j++)
ans=min(ans,a[j]);
}
if(r-l+1>=m)l++;
r++;
}
return 0;
}