轉(zhuǎn)自yyr博客(https://www.luogu.org/blog/yeyangrui/)
(主要是想收錄他的)
這一道題的主要思路:單調(diào)隊列(不熟的可以做一下滑動窗口這一道題)**(表示蒟蒻不會ST表)
建立一個從小到大的單調(diào)隊列职员,每次如果讀入到比隊尾的數(shù)小就將隊尾的數(shù)彈出(貪心思想:你后面都有更小值的了你還要前面的干什么呢跛溉?反而長度更長更容易失效)扮授,另外不要忘了將已經(jīng)超出整個序列長度的物體從隊首彈出专肪,的而每一組的答案就是這個單調(diào)隊列的隊首元素**
代碼如下:
#include<iostream>
#include<cstdio>
using namespace std;
int a[1000001];
struct node
{
int a;//物體的質(zhì)量
int b;//物體的位置
}b[1000001];
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int n,m,head=1,top=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)//前m個數(shù)可以直接進(jìn)入隊列,不需要考慮超出長度的問題
{
while(head<=top&&b[top].a>=a[i])//將隊尾較大元素彈出(建立單調(diào)隊列)
top--;
b[++top].a=a[i];//將當(dāng)前元素加入隊列中
b[top].b=i;
}
cout<<b[head].a<<endl;//輸出第一個序列中的最小值
for(int i=m+1;i<=n;i++)
{
while(head<=top&&b[head].b<=i-m)//將隊首已經(jīng)超出序列長度的元素彈出
head++;
while(head<=top&&b[top].a>=a[i])//將隊尾較大元素彈出(建立單調(diào)隊列)
top--;
b[++top].a=a[i];//將元素壓入隊列中
b[top].b=i;
cout<<b[head].a<<endl;//輸出當(dāng)前序列最小值
}
return 0;
}