单调队列顾名思义就是一个单调的队列。下面分析一下用它来干什么,以及怎么样维护。
先来个问题说明一下吧。
有一些学生来找我面试(宝宝是HR哦),我让他们进屋排队,现在我不定时的询问在屋里的最高分。让面试完的出屋,同时也根据我的心情让面试者进屋。
我的描述不是很好,不明白的自行看题吧
题目
其实这就是在根据条件维护一个特殊的序列,是这个序列保持某种性质。(现在是维护单调的性质)。
目的在于简化查询,特点是不定时的更新序列,不定的查询。
下面介绍一下实现思想:以单增队列为例:维护一个序列,元素如果比最后一个元素小,把这个元素放到最后,如果不比最后一个元素小的话,就从前向后遍历,直到找到一个值比现在的元素小,就用现在的元素代替这个值,并且将其后面的全舍掉。(先到于实际队列中的那些人公用这个最大值)
下面上代码;
#include<cstdio>
#include<iostream>
#include<cstring>
int a[1000010];
int b[1000010];
using namespace std;
int main()
{
int T,v,shu,t1,t2,t,w;
char temp[100],s[100];
scanf("%d",&T);
while(T--)
{
t = 0;
t1 = 0;\\现实队列的队头
w = 0;\\尾序号
t2 = 0;\\所维护队列的对头
shu = 0//用来记录当前的人数;
memset(a, -1 ,sizeof(a));
memset(b,-1,sizeof(b));
while(1){
scanf("%s",temp);
if(strcmp(temp,"END") == 0)
{
break;
}
if(strcmp(temp,"C") == 0)
{
scanf("%s%d",s,&v);
a[t++] = v;
shu++;
if(b[w] >= v)
{
b[++w] = v;
}
else
{
for(int i = t2; b[i] != -1||w == 0;++i)
{
if(v > b[i])
{
b[i] = v;
w = i;
b[i + 1] = -1 ;
break;
}
}
}
}
if(strcmp(temp,"G") == 0)
{
if(shu != 0)
{
if(a[t1] == b[t2])
{
t2++;
}
t1++;
shu--;
}
}
if(strcmp(temp,"Q") == 0)
{
if(shu != 0)
{
printf("%d\n",b[t2]);
}
else
{
printf("-1\n");
}
}
}
}
return 0;
}