分析:很明显的一道单调队列,为什么呢?后来加入队伍的人(注意是题目的队伍而不是代码中的队列,后文也要注意区别队伍和队列),如果通过查找把它插到递减队列中对应的位置,而不用维护其后面的值。因为在这个新人出队之前,在它前面来的人(准确的说是RP更低的被抛弃的那些人)是不可能成为Q的结果的,也就不用再维护了。
同时我们记录一个总出现人数n和已经面试完的人数out,每次Q如果out==n,说明没有人排队,输出-1,否则输出队首元素,因为此时是RP最高的人。对于G,如果out的人已经波及到队首元素的pos,即out>pos[queue[l]],那么说明RP最高者已经不是队首了,因为他已经out,则队首向前进发即l++ 。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <map> using namespace std; const int N = 1000010; long long que[N], rp[N]; char str[20]; int main() { int t; scanf("%d", &t); while(t--) { scanf("%s",str); int r=-1, l=0, n=0, out=0; while(scanf("%s",str),str[0]!='E') { if(str[0]=='C') { scanf("%s",str); scanf("%lld",&rp[++n]); while(l<=r&&rp[que[r]]<rp[n]) r--; que[++r]=n; } else if(str[0]=='G') { out++; while(out>=que[l]) { l++; } } else if(str[0]=='Q') { if(out>=n) { printf("-1\n"); } else { printf("%lld\n",rp[que[l]]); } } } } return 0; } | ![]() |
Description Input
Output Sample Input 2 START C Tiny 1000000000 C Lina 0 Q G Q END START Q C ccQ 200 C cxw 100 Q G Q C wzc 500 Q END Sample Output 1000000000 0 -1 200 100 500 Hint
数据较大建议使用scanf,printf 不推荐使用STL
Source
福州大学第七届程序设计竞赛
| ![]() |