如果是Q命令,则判断当前队列中是否仍有元素,如果没有则输出-1,如果有则直接输出队首。
如果是G命令,则对last加1,之后对于队列中所有超出范围的前端元素进行出队操作。(该元素在原序列中的位置>=last)
如果是C命令,则将该元素加入队列中,并和队尾元素比较,维护队列的单调性。
这里考虑一个问题,当前元素加如后对队尾元素为什么可以毫无保留的删去呢?
因为当前加入的元素比队尾元素大,且该元素比队尾元素入队晚(也就是该元素比队尾元素晚出队),所以只要该元素在队列中,就一定不会选取队尾元素。也就是当前状态一定比队尾元素的状态更优。——这里一定要理解深刻,这是队列的本质。
因此,这题的单调队列中维护的一个属性是元素的价值,一个属性是单调队列中的元素在原序列中的位置。
#include<stdio.h>
#include<string.h>
const int maxn=1000001;
struct ss
{
int x;
int value;
};
ss que[maxn];
int main()
{
//freopen("Input.txt","r",stdin);
int ca;
char sa[10],name[10];
scanf("%d",&ca);
while(ca--)
{
int beg=-1,last=0,tmp,head=0,num=1;
scanf(" %s",name);
while(scanf(" %s",sa)&&strcmp(sa,"END")!=0)
{
if(sa[0]=='C')
{
scanf(" %s%d",name,&tmp);
while(beg>=head&&que[beg].value<=tmp) beg--;
que[++beg].x=num++;
que[beg].value=tmp;
}
else if(sa[0]=='Q')
{
while(head<=beg&&que[head].x<=last) head++;
if(head>beg) printf("-1\n");
else printf("%d\n",que[head].value);
}
else last++;
}
}
return 0;
}