題目描述
一個含有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
【算法分析】這個題時間上就是一個單調隊列的模板題目,求滑動窗口的最值,我們單調隊列一般分爲3步,1,元素超出了,出隊,2冗餘元素,3當前元素入隊,這裏當我們枚舉i的時候,實際上我們是求i-1之前的m個元素。對於第一個我們特殊處理就可以了。 還有一個就是這裏的數據是2*10^7那麼這裏我們只有用scanf和print才能過。
【代碼實現】
#include<bits/stdc++.h>
using namespace std;
const int N=2000010;
int a[N],q[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int hh=0,tt=0;
printf("0\n");
q[hh]=1;
for(int i=2;i<=n;i++)
{
if(hh<tt&&i-1-q[hh]+1>m) hh++;
while(hh<tt&&a[q[tt-1]]>=a[i-1]) tt--;
q[tt++]=i-1;
printf("%d\n",a[q[hh]]);
}
return 0;
}