今天上午学了一波单调队列,然后学完单调队列后领悟到了一点小思路,hhh,然后我就在单调队列的基础上进行了改进,仅仅限制了进入队列中的元素个数,然后按照单调性,进行不断去除,然后输出个数即可。
注意1:单调队列,单调栈写这种题一般存的是坐标,这样才能进行新老元素的更换
注意2:这题我用线段树也A了,但是注意这道题给了1e6的数据范围,因为题目水了,后台数据只有1e5,所以我们可以用线段树过,但是如果数据是1e6,线段树需要开4倍空间,所以过不了这道题,这题给定内存限制小于1e6*4
我们来看一下1e5数据下,单调队列修改的代码和线段树的代码所用的内存大小:
单调队列:
线段树:
这就是在解决特定问题上单调队列或者单调栈和线段树的差别,所以多学习点新知识才会进步。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int q[maxn],a[maxn];
int n,k;
void solv()
{
int head=0,tail=-1,id;
bool fla=true;
for(int i=0; i<n; i++)
{
while(head<=tail&&n-q[tail]-1>=k&&a[q[tail]]<a[i]&&fla)
tail--;
if(n-q[tail]-1>=k&&fla)
q[++tail]=i;
else
{
fla=false;
int x=q[tail];
while((n-x-1)>(k-tail-1)&&a[q[tail]]<a[i])
tail--;
q[++tail]=i;
}
}
for(int i=0; i<k; i++)
{
if(i==k-1)
cout<<a[q[i]]<<endl;
else
cout<<a[q[i]]<<' ';
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>k)
{
for(int i=0; i<n; i++)
cin>>a[i];
solv();
}
}